はじめに
以下の記事の応用編を書いてみました。
「...」の使い方(応用編)
インターフェース型での可変長引数
Goの可変長引数は、インターフェース型を利用することで、異なる型の引数を一つの関数で受け取ることができます。これは特に、ログ出力や汎用的な処理を行う関数を作成する際に便利です。
func WriteMultipleTypes(values ...interface{}) {
for _, value := range values {
fmt.Println(value)
}
}
func main() {
WriteMultipleTypes(1, "two", 3.0)
}
// 実行結果
1
two
3
外部からオプションを設定する
外部からオプションを設定する一般的な例として、設定オブジェクトや構造体を初期化する関数を考えてみましょう。このアプローチは、設定が多く、柔軟性が必要な場合に特に有用です。
package main
import (
"fmt"
)
// Config はアプリケーションの設定を保持する構造体です。
type Config struct {
Host string
Port int
IsSecure bool
}
// Option は Config を変更する関数です。
type Option func(*Config)
// NewConfig は新しい Config を生成し、与えられたオプションでカスタマイズします。
func NewConfig(options ...Option) *Config {
config := &Config{
Host: "localhost",
Port: 8080,
IsSecure: false,
}
for _, option := range options {
option(config)
}
return config
}
// WithHost はホスト名を設定する Option を返します。
func WithHost(host string) Option {
return func(c *Config) {
c.Host = host
}
}
// WithPort はポート番号を設定する Option を返します。
func WithPort(port int) Option {
return func(c *Config) {
c.Port = port
}
}
// WithSecurity はセキュリティの有効化を設定する Option を返します。
func WithSecurity(isSecure bool) Option {
return func(c *Config) {
c.IsSecure = isSecure
}
}
func main() {
// カスタムオプションを使用して Config を作成
config := NewConfig(
WithHost("example.com"),
WithPort(443),
WithSecurity(true),
)
fmt.Printf("Config: %+v\n", config)
}
// 実行結果
Config: &{Host:example.com Port:443 IsSecure:true}
このコードでは、Config 構造体を初期化し、その後に複数のオプション関数(WithHost、WithPort、WithSecurity)を適用しています。これにより、外部から柔軟に設定を変更することが可能になります。
外部からオプションを設定する(シンプルver.)
こちらは1つ前のパターンと本質的には同じです。
ここでは、GenerateUserの引数でfunc(data *User)の可変長引数を取る形になっております。
package main
import (
"fmt"
"testing"
)
type User struct {
ID uint64
Name string
}
func GenerateUser(options ...func(data *User)) User {
result := User{
ID: 1,
Name: "default",
}
for _, option := range options {
option(&result)
}
return result
}
func TestSomething(t *testing.T) {
defaultUser := GenerateUser()
updatedUser := GenerateUser(func(data *User) {
data.ID = 999
data.Name = "updated"
})
fmt.Printf("defaultUser %+v\n", defaultUser)
fmt.Printf("updatedUser %+v\n", updatedUser)
// ...
// add assertions
}
// 実行結果
defaultUser {ID:1 Name:default}
updatedUser {ID:999 Name:updated}
まとめ
これらの例を通して、可変長引数 ... の強力な用途とその応用方法を紹介しました。Go言語におけるこの機能は、コードの柔軟性と再利用性を大いに高めることができます。ぜひあなたのコードで活用してみてください!