Option, empty, null and pointers

Hi everyone

I’m a bit confused about go. Go has no ‘null’ value what is a good pattern I think but there is no concept of Option.

When reading the documentation pointers are used to decide if something is passed by reference or passed by value. So choosing to use pointers is a matter of mutability, same instances and performance.

Because there is no option a common pattern is to use pointers if a value can be empty (nil pointer). So choosing a pointer is suddendly a matter of if something can be nothing.

What is the right way to handle this? Just live with mixed concepts?

1 Like

The way I program in Go is different from the way I program in, e.g., C# with its new nullability features where you only need to put a ? after a type name to make it optional. The way I indicate that something is optional in Go depends on a lot of context. For example, for functions whose parameters are optional, if only one or two parameters are optional, I usually make separate functions (e.g. instead of NewThing, have also NewThingWithContext, etc.). If more configurability is needed than that, I use “functional options”:

So instead of:

package mypkg

func NewThing(timeout *time.Duration) (*Thing, error) {
    // ...
}
thingA, err := mypkg.NewThing(nil)

d := 5 * time.Second
thingB, err := mypkg.NewThing(&d)

I do something more like:

package mypkg

type ThingOption func(t *Thing) error

func NewThing(options ...ThingOption) (*Thing, error) {
    // ...
}
myThing, err := mypkg.NewThing(
	mypkg.ThingTimeout(5 * time.Second),
)

It’s more verbose, but I like the pattern.

If you mean that struct field values are optional, depending on the value’s type, I might just use a sentinel value, e.g.:

type MyStruct struct {
    // Timeout for an operation.  If 0, no timeout is set.
    Timeout time.Duration
}

Or if it’s very common to use this optional type throughout my package, I might define an optional type for it:

type OptionalTimeout struct {
    // HasDuration is set when the Duration field's value should be
    // respected.  A Duration of 0 when HasDuration is true indicates
    // that the operation should be aborted immediately
    HasDuration bool

    Duration time.Duration
}

If you mean some other context other than struct fields or function parameters, I’d need to see the specifics to describe what I would do in that situation.

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.