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.
Assignment = ExpressionList assign_op ExpressionList . assign_op = [ add_op | mul_op ] "=" .
The most notable thing so far is that you can do multiple assignments as a single statement. These two code snippets are equivalent:
x = 5
y = 12
x, y = 5, 12
Each left-hand side operand must be addressable, a map index expression, or (for = assignments only) the blank identifier.
That all makes sense… but why on earth would you ever assign something to the blank identifier (_
)?
Three common reasons:
-
You want to discard one of multiple values of the right-hand side of a multi-value expression. Most commonly, a function call:
// Discard the bar value foo, _, err := returnFooAndBar()
-
To do a compile-time type check, without actually assigning anything.
var myCloser struct{ /* ... */ } // This will fail to compile if `*myCloser` doesn't have the proper Close() method var _ io.Closer = (*myCloser)(nil)
-
To satisfy the compiler’s “no unused variables” rule.
x := 3 _ = x // Now 'x' is considered "used", even if it's not referenced anywhere else
This use is most common as a temporary measure, when you’re mid-implementation. Try not to leave such code around for long.
… Operands may be parenthesized.
x = 1 *p = f() a[i] = 23 (k) = <-ch // same as: k = <-ch
I don’t know of any reason you ever would want to parenthesize operands. Maybe it improves readability in some cases?
Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)