首先定义一个选项类型。

type options struct {
    opt1 int,
    opt2 string,
	//...
}

以及可以修改这个选项的函数类型

type Option func(o *options)

然后在初始化函数中通过可变长参数接收任意多个Option函数,在内部运行函数得以对选项进行修改,这样传递了多少参数就设置多少选项。

type Instance struct {
    option options,
}
 
func NewInstance(opts ...Option) *Instance {
    options := options {
        opt1: 1,
        opt2: "xxx",
    }
	// 对参数进行修改
    for _, option := opts {
        option(options)
    }
 
    return &Instance{
        option : options
    }
}

这样只要能够提供Option类型函数,那么就可以对其进行设置,一般都是为每一个选项提供一个函数,让用户可以自己生成需要的Option函数。

func WithOpt1(opt1 int) Option {
	return func(o *options) {
		o.opt1 = opt1
	}
}
 
func WithOpt2(opt2 string) Option {
	return func(o *options) {
		o.opt2 = opt2
	}
}

这里其实产生的是闭包,因为它捕获了环境中的上下文。

用户可以通过提供的Withxxx获得对每个选项进行修改的Option。

最后进行以下测试

func TestOption(t *testing.T) {
    option1 := WithOpt1(2)
    option2 := WithOpt2("option2")
 
    ins := NewInstance(option1, option2)
    t.Log(ins)
}

tags: 设计模式