如何在Go中提供可选参数?

问题描述 投票:1回答:2

我来自Node.js背景,一个典型的模式是有一个函数,它接受一个options对象,即你为可选参数设置属性的对象,例如:

foo({
  bar: 23,
  baz: 42
});

这是JavaScript与可选和命名参数的“等效”。

现在我已经知道Go中没有可选参数,除了可变参数,但它们缺乏命名参数的可读性。所以通常的模式似乎是移交结构。

OTOH结构不能用默认值定义,所以我需要一个函数来设置结构。

所以我最终得到:

  • 调用一个创建结构的函数,然后用默认值填充它。
  • 覆盖我想要改变的值。
  • 调用我实际想要调用的函数并移交结构。

与JavaScript的解决方案相比,这是非常复杂和冗长的。

这实际上是在Go中处理可选和命名参数的惯用方法,还是有更简单的版本?

go optional-parameters named-parameters
2个回答
4
投票

有什么办法可以利用零值吗?所有数据类型都被初始化为零值,因此这是一种默认逻辑形式。

选项对象是一种非常常见的习语。 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个默认的信息/逻辑片段以避免这种情况。


0
投票

这种方法是否有用取决于场景,但在某些情况下,至少你可以使用map

如果所有选项都属于同一类型,请使用map[string]type。这可以为您提供命名选项,并根据需要提供少量或多种选项。

他们的存在很容易用类似的东西来测试

if val, exists := opts["bar"]; exists {
    // Do something here
}

要设置默认值,您可以在创建地图时使用地图文字。

如果选项的类型不同,则可以使用map[string]interface{},这将允许任何类型存储在地图中。您只需要在检索后对值进行类型转换。

© www.soinside.com 2019 - 2024. All rights reserved.