Reputation: 5746
I am writing a package that exposes this function:
func Marshal(input interface{}) ([]byte, error)
This is fine for the majority of situations, but I also want to prove another function if there are extra options:
type MarshalOptions struct {
OnlyStdClass bool
}
My first thought is to create another function:
func MarshalWithOptions(input interface{}, options MarshalOptions) ([]byte, error)
Is this the recommended way of doing this? Is there a standard naming convention for function that also provide a more specific version with options?
Upvotes: 1
Views: 169
Reputation: 5746
I found this to the be the best balance between explicit and simplicity:
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) {
// ...
}
Using the constructor pattern I can set reasonable defaults, without requiring that every option (especially if they may change) are explicitly set.
It's true that I could accept nil
, but I don't because it makes it more explicit to read:
result := Marshal(123, DefaultMarshalOptions())
Upvotes: 0
Reputation: 5289
You can take a *MarshalOptions
. The caller can then pass nil
if they want the default behavior.
eg.
func Marshal(input interface{}, options *MarshalOptions) ([]byte, error)
Upvotes: 0
Reputation: 6739
One common way of doing that is to declare the function as variadic so that it accepts zero or more options. Assuming Option
is your option type, you would declare it like this:
func Marshal(input interface{}, options ...Option) ([]byte, error)
Then, within the function, options
has the type []Option
.
The function would then be called with zero or more Option
arguments:
bytes, err := Marshal(input, Option1, Option2)
Or, if you have your options in a slice, you would call it like this:
bytes, err := Marshal(input, options...)
There are several references to this in the language spec (look for "variadic").
Upvotes: 1