结构体的导出

一个关于解决配置项问题的例子

下面这个例子中,要解决的是在执行时,可以灵活设置所有配置项。
而且这个配置项还有可能会持续变化和增长。
例子开发的是一个Go语言包,该包种有一个操作 Foo:

// 通过Option进行所有选项的设置,传入的选项是一个option类型的函数,这个函数可以设置一个指定的选项
// option类型是:type option func (*Foo)
// 代码如下:
func (f *Foo)Option(opts ...option) {
  for _, opt := range opts {
    opt(f) // 遍历执行传入的设置选项函数,这个函数的参数都是Foo对象本身,用于修改Foo对象的选项配置
  }
}

// 下面是一个选项的函数实例,设置:
func Verbosity(v int) option {
  return func(f *Foo){
    f.verbosity = v
  }
}

// 下面是调用实例, 选项设置并不需要修改Foo的代码:
foo.Option(pkg.Verbosity(3))

// ------------------------------------------
// 下面是在上面的基础上,在设置选项参数同时返回设置之前的初值:
type option func(*Foo) interface{}

func Verbosity(v int) option {
  return func(f *Foo) interface{
    prev := f.verbosity
    f.verbosity = v
    return prev
  }
}

func(f *Foo)Option(opts ...option) (prev interface{}){
  for _, opt := range opts {
    prev = opt(f)
  }
  return prev
}
// 调用实例
preVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeThing()
foo.Option(pkg.Verbosity(preVerbosity.(int)))

// -----------------------------------------
// 上面的类型判断何有些笨茁,下面是优化
type option func(*Foo) option

func Verbosity(v int) option {
  return func(f *Foo) option {
    prev := f.verbosity
    f.verbosity = v
    return Verbosity(prev)
  }
}

func(f *Foo)Option(opts ...option) (prev option){
  for _, opt := range opts {
    prev = opt(f)
  }
  return prev
}
// 调用实例
preVerbosity := foo.Option(pkg.Verbosity(3))
foo.DoSomeThing()
foo.Option(preVerbosity)


参考文献

  1. 自引用函数与设计


blog comments powered by Disqus
—  原创作品许可 — 署名-非商业性使用-禁止演绎 3.0 未本地化版本 — CC BY-NC-ND 3.0   —