我来自Node.js背景,一个典型的模式是有一个函数,它接受一个options对象,即你为可选参数设置属性的对象,例如:
foo({
bar: 23,
baz: 42
});
这是JavaScript与可选和命名参数的“等效”。
现在我已经知道Go中没有可选参数,除了可变参数,但它们缺乏命名参数的可读性。所以通常的模式似乎是移交结构。
OTOH结构不能用默认值定义,所以我需要一个函数来设置结构。
所以我最终得到:
与JavaScript的解决方案相比,这是非常复杂和冗长的。
这实际上是在Go中处理可选和命名参数的惯用方法,还是有更简单的版本?
有什么办法可以利用零值吗?所有数据类型都被初始化为零值,因此这是一种默认逻辑形式。
选项对象是一种非常常见的习语。 etcd client library有一些类似于以下的示例(SetOptions,GetOptions,DeleteOptions)。
type MyOptions struct {
Field1 int // zero value (default) of int is 0
Field2 string // zero value (default) of string is ""
}
func DoAction(arg1, arg2 string, options *MyOptions){
var defaultValue1 int = 30 // some reasonable default
var defaultValue2 string = "west" // some reasonable default
if options != nil {
defaultValue1 = options.Field1 // override with our values
defaultValue2 = options.Field2
}
doStuffWithValues
一个相关的问题(在Go的思维模式中)将是,你需要这种复杂性吗?灵活性很好,但标准库中的大多数事情都试图一次只处理1个默认的信息/逻辑片段以避免这种情况。
这种方法是否有用取决于场景,但在某些情况下,至少你可以使用map
。
如果所有选项都属于同一类型,请使用map[string]type
。这可以为您提供命名选项,并根据需要提供少量或多种选项。
他们的存在很容易用类似的东西来测试
if val, exists := opts["bar"]; exists {
// Do something here
}
要设置默认值,您可以在创建地图时使用地图文字。
如果选项的类型不同,则可以使用map[string]interface{}
,这将允许任何类型存储在地图中。您只需要在检索后对值进行类型转换。