1

I'm coming from a Node.js background, and there a typical pattern is to have a function which takes an options object, i.e. an object where you set properties for optional parameters, such as:

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

This is JavaScript's "equivalent" to optional and named parameters.

Now I have learnt that there are no optional parameters in Go, except variadic parameters, but they lack the readability of named parameters. So the usual pattern seems to be to hand over a struct.

OTOH a struct can not be defined with default values, so I need a function to set up the struct.

So I end up with:

  • Call a function that creates the struct and then fills it with default values.
  • Overwrite the values I would like to change.
  • Call the function I actually want to call and hand over the struct.

That's quite complicated and lengthy compared to JavaScript's solution.

Is this actually the idiomatic way of dealing with optional and named parameters in Go, or is there a simpler version?

Golo Roden
  • 140,679
  • 96
  • 298
  • 425

1 Answers1

4

Is there any way that you can take advantage of zero values? All data types get initialized to a zero value, so that is a form of default logic.

An options object is a pretty common idiom. The etcd client library has some examples (SetOptions,GetOptions,DeleteOptions) similar to the following.

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

An relevant question (and very much in the mindset of Go) would be, do you need this kind of complexity? The flexibility is nice, but most things in the standard library try to only deal with 1 default piece of info/logic at a time to avoid this.

matt.s
  • 1,698
  • 1
  • 20
  • 29
  • My argument is that having optional named parameters **reduces complexity**. They reduce the explosion of methods required to deal with multiple permutations, eliminate the need to come up with meaningful, discoverable and rememberable names for those methods, and simplify learning of the packages that use methods of that nature. Also, your example does not address defaulting when `MyOptions` is not `nil` but `Field2` is empty. Which bring us back full circle to the issue the OP complained about. – MikeSchinkel Mar 20 '19 at 14:01
  • @MikeSchinkel, I think you're misinterpreting me. – matt.s Mar 20 '19 at 14:10
  • Maybe you can elaborate? – MikeSchinkel Mar 20 '19 at 14:12
  • 1
    Sorry, hit enter too fast. My first comment is encouraging the OP (or anyone) to think about if that's the best solution. Optional args are a good way to reduce complexity, but we should think about if it's the right fit for this problem. My second comment is that zero values are a language feature/idiom that we can use to reduce complexity, taking advantage of them seems like a good idea. PS your comment helped me catch a mistake, thanks! – matt.s Mar 20 '19 at 14:19
  • Thanks for clarifying. As a former StackExchange moderator on another site I became steeped in the following philosophy of answering questions _"**First answer the question**, and then — **and only then** — encourage the asker to think differently about the problem if you feel the need to do so."_ . So answers that start with questioning that asker why they need what they are asking for have always been one of my bigger pet peeves. #fwiw – MikeSchinkel Mar 20 '19 at 17:02
  • 1
    @MikeSchinkel, I'll keep that in mind; answer updated to include your advice (plus some more comments). – matt.s Mar 20 '19 at 18:22
  • Much better, thank you. I reverse my downvote to an upvote. – MikeSchinkel Mar 20 '19 at 23:44