LoginSignup
3
0

[Go]「...(ピリオド3つ)」の使い方(応用編)

Last updated at Posted at 2023-11-25

はじめに

以下の記事の応用編を書いてみました。

「...」の使い方(応用編)

インターフェース型での可変長引数

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言語におけるこの機能は、コードの柔軟性と再利用性を大いに高めることができます。ぜひあなたのコードで活用してみてください!

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0