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

时间:2017-03-14 02:45:21

标签: go

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

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

这适用于大多数情况,但如果有额外选项,我也想证明另一个功能:

type MarshalOptions struct {
    OnlyStdClass bool
}

我的第一个想法是创建另一个功能:

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

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

3 个答案:

答案 0 :(得分:1)

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

Option

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

然后使用零个或多个[]Option参数调用该函数:

Option

或者,如果您在切片中有选项,则可以这样称呼它:

bytes, err := Marshal(input, Option1, Option2)

language spec中有几个对此的引用(寻找“可变”)。

答案 1 :(得分:0)

您可以选择*MarshalOptions。如果调用者想要默认行为,则可以传递nil

例如。 func Marshal(input interface{}, options *MarshalOptions) ([]byte, error)

答案 2 :(得分:0)

我发现这是显性和简单之间的最佳平衡:

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())