Multiple Return Values
Latest update: November 30, 2022

Multiple Return Values #

Go has a built-in concept of multiple return values:

func foo() (int, int) {
	return 1, 2
}

// ...

a,b := foo()

These resemble tuples from other programming languages, but are simpler and more limtied. For example, you cannot assign the result of a multiple-return function to a single variable:

res := foo()
// ERR: assignment mismatch: 1 variable but foo returns 2 values

Neither, can you get one or more of the values using indexing:

a := foo()[0]
// ERR: multiple-value foo() (value of type (int, int)) in single-value context

What is possible, though, is ignoring one or more of the return values. To do that, we still need toexpect all the possible return values, and use _ for those we want to ignore:

a, _ := foo()
_, b := foo()

Usage #

Multiple return values are most often used in error handling. Go’s way of error handling is to return an error value alongside the usually expected result. This error value is then checked on the caller side:

res, err := someDifficultOp()
if err != nil {
	// handle the err. Most like, we don't proceed from here
}
Some claimed that this pattern was established early on, because Go did not have generic type parameters until much later (v 1.18 as of March 2022). However, it is arguable how much generics would have helped here, since the language does not and will possibly never have a built-in concept of monads.

Note that the result-error pattern is not mutually exclusive. In other words, returning a non-nil error value does not exclude the presence of a result value.

To be continued …