是否有一种将选项传递给Go函数的规范方法?

是否有一种将选项传递给Go函数的规范方法?,go,Go,我正在编写一个公开此函数的包: func Marshal(input interface{}) ([]byte, error) func MarshalWithOptions(input interface{}, options MarshalOptions) ([]byte, error) 这在大多数情况下都很好,但如果有额外的选项,我还想证明另一个函数: type MarshalOptions struct { OnlyStdClass bool } 我的第一个想法是创建另一个

我正在编写一个公开此函数的包:

func Marshal(input interface{}) ([]byte, error)
func MarshalWithOptions(input interface{}, options MarshalOptions) ([]byte, error)
这在大多数情况下都很好,但如果有额外的选项,我还想证明另一个函数:

type MarshalOptions struct {
    OnlyStdClass bool
}
我的第一个想法是创建另一个函数:

func Marshal(input interface{}) ([]byte, error)
func MarshalWithOptions(input interface{}, options MarshalOptions) ([]byte, error)

这是推荐的方法吗?是否有一个标准的函数命名约定,它也提供了一个更具体的选项版本?

一种常见的方法是将函数声明为可变变量,以便它接受零个或多个选项。假设
Option
是您的选项类型,您可以这样声明它:

func Marshal(input interface{}, options ...Option) ([]byte, error)
bytes, err := Marshal(input, options...)
然后,在函数中,
选项
的类型为
[]选项

然后将使用零个或多个
选项
参数调用该函数:

bytes, err := Marshal(input, Option1, Option2)
或者,如果您在一个片段中有您的选项,您可以这样称呼它:

func Marshal(input interface{}, options ...Option) ([]byte, error)
bytes, err := Marshal(input, options...)

在(查找“variadic”)中有几处对此的引用。

您可以使用
*marshalloptions
。如果调用方想要默认行为,则可以传递
nil

例如。
func封送(输入接口{},选项*封送选项)([]字节,错误)
我发现这是显式和简单性之间的最佳平衡:

type MarshalOptions struct {
    OnlyStdClass bool
}

// DefaultMarshalOptions will create a new instance of MarshalOptions with
// sensible defaults. See MarshalOptions for a full description of options.
func DefaultMarshalOptions() *MarshalOptions {
    options := new(MarshalOptions)
    options.OnlyStdClass = false

    return options
}

func Marshal(input interface{}, options *MarshalOptions) ([]byte, error) {
    // ...
}
使用构造函数模式,我可以设置合理的默认值,而不需要显式地设置每个选项(特别是在它们可能更改的情况下)

诚然,我可以接受
nil
,但我不接受,因为这样可以更明确地阅读:

result := Marshal(123, DefaultMarshalOptions())

可能是相关的(特别是附加链接),请参阅此方法的详细示例。另请参阅Dave Cheney的“不要害怕第一类函数”()我认为有一些有效的答案(这就是为什么我首先问这个问题),但我个人最喜欢这个。我已经发布了一个非常类似的答案,我已经确定了。