自引用函数和配置设计

最近发现一篇文章Self-referential functions and the design of options介绍了一种很好的实现配置的方式,目前这种方式 在许多的开源库中被使用,比如GRPC:

conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))

例子

首先定义一个配置接口:

type option func(*Foo)

这里Foo就是我们需要实际操作的对象

之后我们实现一个加载配置的方法:

func (f *Foo) Option(opts ...option) {
    for _, opt := range opts {
        opt(f)
    }
}

这里通过变长参数的方式将所有的option执行。

下面实现一个具体的配置项:

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

通过闭包的方式构造一个option的函数,最后调用:

foo.Option(pkg.Verbosity(3))

当然最后可以依据实际情况进行改造,原文中还对这种方法做了一点改进,这里就不说了,个人感觉grpc这种方式已经够大部分场景下使用了。

Licensed under CC BY-NC-SA 4.0