Tuple assignments

May 1, 2024

Yesterday (as well as in earlier emails) I mentioned multiple-assignments in a single statement. Today we see how they’re defined to work. As such, there’s not really an new material here, but we’ll cover it just the same.

Assignment statements

A tuple assignment assigns the individual elements of a multi-valued operation to a list of variables. There are two forms. In the first, the right hand operand is a single multi-valued expression such as a function call, a channel or map operation, or a type assertion. The number of operands on the left hand side must match the number of values. For instance, if f is a function returning two values,

x, y = f()

assigns the first value to x and the second to y. In the second form, the number of operands on the left must equal the number of expressions on the right, each of which must be single-valued, and the nth expression on the right is assigned to the _n_th operand on the left:

one, two, three = '一', '二', '三'

So the two forms are:

  • Multiple return values from a single function
  • Multiple single-value expressions, separated by commas.

And you can’t mix them.

That is:

one, two, three := foo(), "three"

is invalid. You need to break this into two statements:

one, two := foo()
three := "three"

The blank identifier provides a way to ignore right-hand side values in an assignment:

_ = x       // evaluate x but ignore it
x, _ = f()  // evaluate f() but ignore second result value

By far the most common use of the blank identifier is to discard return values you don’t care about from a multi-value function.

As a simple example that is likely familiar if you’ve done any REST programming:

ct, _, err := mime.ParseMediaType(req.Header.Get("Content-Type"))

The other example usage is to evaluate, but ignore a variable. This is only really useful as a way to fool the compiler into letting you keep (hopefully temporarily) unused variables in your code.

var x = "Something interesting"

_ = x // Without this, the compiler will complain that `x` is defined, but not used

Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Assignment statements

Assignment statements An assignment replaces the current value stored in a variable with a new value specified by an expression. Assignments should be familiar to you. They’re pretty fundamental to almost all programming languages. But there are a few aspects to Go’s assignments that are worth calling out. … An assignment statement may assign a single value to a single variable, or multiple values to a matching number of variables.


Built-in functions

We’ve just finished up the rather long section on different types of statements. There’s only a few more sections in the spec, before we finish this series. And today we start looking at Built-in functions! Built-in functions Built-in functions are predeclared. They are called like any other function but some of them accept a type instead of an expression as the first argument. The built-in functions do not have standard Go types, so they can only appear in call expressions; they cannot be used as function values.


Go statements, conclusion

Today we finish the description of go statements: Go statements … When the function terminates, its goroutine also terminates. If the function has any return values, they are discarded when the function completes. go Server() go func(ch chan<- bool) { for { sleep(10); ch <- true }} (c) Okay, so that bit about discarding return values makes sense, right? func main() { go sum(1, 3) // return value discarded } func sum(a, b int) int { return a + b } But what if you need that return value for something?

Get daily content like this in your inbox!

Subscribe