Is it acceptable to make the optional parameter as varargs

204 views
Skip to first unread message

Amarjeet Anand

unread,
May 24, 2020, 10:59:00 PM5/24/20
to golang-nuts
Is it acceptable to make the optional parameter as varargs?
I wrote code in my package like ...


package backoff

func New(options ...Options) *backOff {
backOff := defaultBackOff()
if len(options) == 0 {
return backOff
}

// override default values
if len(options) > 1 {
panic("only 1 backOffOption allowed")
}
optn := options[0]
backOff.options = &optn

if optn.Delay_ms > 0 {
backOff.delay_ms = optn.Delay_ms
}
return backOff
}


So that in other package, it can be used as backoff.New() when option is not needed(which will be the case most of the time).

Is using varargs for optional parameter is ok? Or am I abusing the Variadic Functions feature?





James

unread,
May 24, 2020, 11:31:46 PM5/24/20
to Amarjeet Anand, golang-nuts
This reminds me of functional options which I think are used quite widely for this purpose.


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/CANFuhy8nhhbBDWb0%3D7SLvq1aictC9GVG%3D9zpfpJ1gevDdRmd6A%40mail.gmail.com.

Amarjeet Anand

unread,
May 25, 2020, 12:37:07 AM5/25/20
to James, golang-nuts
Thanks James for your response and the amazing posts.

robert engels

unread,
May 25, 2020, 1:25:35 AM5/25/20
to Amarjeet Anand, James, golang-nuts
I think the Builder pattern is easier than this, and it retains the property of both ‘config struct’ and ‘multiple args’ versions that the implementation can re-order and validate option in aggregate easier - but most of all is doesn’t pollute that package with top-level public functions. The builder pattern uses instance methods to tie the function to the configuration structure,

Amarjeet Anand

unread,
May 25, 2020, 2:12:09 AM5/25/20
to robert engels, Amarjeet Anand, James, golang-nuts
Thanks Robert for the nice idea.
Using builder pattern to set options didn't come to my mind. Looks really clean.

ser...@netdata.cloud

unread,
May 25, 2020, 1:51:33 PM5/25/20
to golang-nuts
Hello Amarjeet,

You can actually don't check if len(options) is greater than one – if your package provides only single implementation of Option, than there is no way to pass something different than that backoffOption. But it also brings an ability to extend your constructor later. There is a great article about optional arguments: https://sagikazarmark.hu/blog/functional-options-on-steroids/

I'd rather prefer optional arguments to builder.

--
Regards,
Sergey.

Robert Engels

unread,
May 25, 2020, 2:29:55 PM5/25/20
to ser...@netdata.cloud, golang-nuts
You can use builder to build options or the server. It is a much cleaner and self documenting method. 

On May 25, 2020, at 12:51 PM, ser...@netdata.cloud wrote:


--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.

boj...@gmail.com

unread,
May 29, 2020, 12:27:50 PM5/29/20
to golang-nuts
I actually published a whole article listing the various patterns for optional parameters, just a few hours ago: https://bojanz.github.io/optional-parameters-go/

Your code looks fine to me, it is a reasonable tradeoff.

roger peppe

unread,
May 29, 2020, 6:03:12 PM5/29/20
to robert engels, Amarjeet Anand, James, golang-nuts
I'm not familiar with the Builder pattern. Could you provide a good example of its use in a Go package?

robert engels

unread,
May 29, 2020, 9:31:15 PM5/29/20
to roger peppe, Amarjeet Anand, James, golang-nuts
NatsIO which is a pretty major application has this https://www.javadoc.io/doc/io.nats/jnats/2.0.0/io/nats/client/Options.Builder.html

This is a pretty good “tutorial” - and I think you can see how it can be applied to parameters or instance creation (e.g. the server instance). see https://vaskoz.wordpress.com/2014/04/07/golang-builder-pattern/
Reply all
Reply to author
Forward
0 new messages