初始版本 #
- 定义option类型。
type option func(*Foo)
其中Foo为需要设置option的对象类型。option是用来设置选项的函数。
- 为Foo类型添加应用options列表的函数Option。
func (f *Foo) Option(opts ...option) {
for _, opt := range opts {
opt(f)
}
}
- 提供设置特定选项(如verbosity)的函数。
func Verbosity(v int) option {
return func(f *Foo) {
f.verbosity = v
}
}
- 客户端设置选项。
foo.Option(pkg.Verbosity(3))
让Option方法返回先前的值 #
用空接口来保存选项值的方案 #
type option func(*Foo) interface{}
func Verbosity(v int) option {
return func(f *Foo) interface{} {
previous := f.verbosity
f.verbosity = v
return previous
}
}
func (f *Foo) Option(opts ...option) (previous interface{}) {
for _, opt := range opts {
previous = opt(f)
}
return previous
}
客户端使用方式如下:
prevVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeDebugging()
foo.Option(pkg.Verbosity(prevVerbosity.(int)))
返回option函数的设置方式 #
空接口显得比较笨重(clumsy),设置选项的返回值是另一个option函数,新返回的option函数在调用时会将值设置为原来的值。
type option(f *Foo) option
// Option sets the options specified.
// It returns an option to restore the last arg's previous value.
func (f *Foo) Option(opts ...option) (previous option) {
for _, opt := range opts {
previous = opt(f)
}
return previous
}
func Verbosity(v int) option {
return func(f *Foo) option {
previous := f.verbosity
f.verbosity = v
return Verbosity(previous)
}
}
尤其要注意最后返回的是Verbosity(previous)。这里返回的是个undo closure。客户端使用方式如下:
prevVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeDebugging()
foo.Option(prevVerbosity)
或者用defer的用法:
func DoSomethingVerbosely(foo *Foo, verbosity int) {
// Could combine the next two lines,
// with some loss of readability.
prev := foo.Option(pkg.Verbosity(verbosity))
defer foo.Option(prev)
// ... do some stuff with foo under high verbosity.
}
From #
Self-referential functions and the design of options