You can, and in fact, that's how idiomatic Go's handled this up until now. But it only works in that specific case, and even then there's a small issue with readability - if you're not already familiar with this pattern, it's not immediately obvious that the string is strongly coupled with the bool. An Optional is very explicit about that.
The problem becomes clearer once you venture out of this exact case. How would you embed this pattern in a struct?
Like so?
type A struct {
value string
valueOK bool
}
Or maybe with a pointer?
type B struct {
value *string
}
This option is the most common one in Go code today.
You can perhaps see the issues already - these are awkward, neither properly communicates that what we want is optionality.
But the real issue is that now that these are in a struct, nothing prevents us from accessing the value without checking if it's valid first:
a := A{value: "", valueOk: false}
// oops
fmt.Println(a.value)
a := B{value: nil}
// oops
fmt.Println(a.value)
This wasn't an issue in your example - if we attempt to only access the value, and omit assigning the bool, the code will not compile:
The problem becomes clearer once you venture out of this exact case. How would you embed this pattern in a struct?
Like so?
Or maybe with a pointer? This option is the most common one in Go code today.You can perhaps see the issues already - these are awkward, neither properly communicates that what we want is optionality.
But the real issue is that now that these are in a struct, nothing prevents us from accessing the value without checking if it's valid first:
This wasn't an issue in your example - if we attempt to only access the value, and omit assigning the bool, the code will not compile: An Optional type fixes this by not allowing you to access the value directly, but to instead have to go through a function like the one above.[1]: https://play.golang.com/p/cJcTD0WWSPO