Description
It is often asked why Go does not have a ternary operator. The Go FAQ says,
The if-else form, although longer, is unquestionably clearer. A language needs only one conditional control flow construct.
However, technically Go has a second form of control flow:
func printer(i int) bool {
fmt.Println(i)
return i%2 != 0
}
func main() {
_ = printer(1) && printer(2) && printer(3)
// Output: 1\n2\n
}
I believe that many of the usecases that people want a ternary operator for could be covered by adding a ??
operator that is similar to &&
but instead short-circuit evaluates non-boolean expressions while the resulting value is a zero-value.
For example, these two snippets would be identical:
port := os.Getenv("PORT")
if port == "" {
port = DefaultPort
}
port := os.Getenv("PORT") ?? DefaultPort
Another use case might be
func New(c http.Client) *APIClient {
return &APIClient{ c ?? http.DefaultClient }
}
In general, ??
would be very useful for setting default values with less boilerplate.
Another use for ??
might be
func write() (err error) {
// ...
defer func() {
closeerr := w.Close()
err = err ?? closeerr
}()
_, err = w.Write(b)
// ...
}
Some rules: ??
should only work if all expressions evaluate to the same type (as is the case for other operators), and ??
should not work for boolean types, since that would cause confusion in the case of a pointer to a bool. If/when Go gets generics, you can trivially write first(ts ...T) T
, so the operator is only worth adding to the language if it has short-circuit evaluation.
In summary, ternary is notoriously unclear, but ??
would not be any more unclear than &&
. I believe it would be more clear than an equivalent if-statement since it would more clearly express the intent of setting a default, non-zero value.