Assignment Operators
Covers simple assignment, compound assignment operators (+=, -=, *=, /=, %=), and multiple assignment semantics in Go
Simple Assignment
A single = sign stores a value in an already declared variable. The expression on the right is fully computed first, and then the result is written to the variable on the left.
var counter int
counter = 10 // assign 10
counter = counter + 1 // read counter, add 1, store back
The variable must exist before = is used. If you try to assign to a name that has not been introduced with var (or with a short variable declaration :=), the compiler will refuse to compile.
Declaration vs. Assignment:
The := token is not an assignment operator. It is a short variable declaration that both declares a new variable and gives it an initial value. Using = on a name that has never been declared causes a compile error: undefined: x. Using := on a name that is already declared in the same scope causes a different compile error: no new variables on left side of :=. Keep the two separate: := creates a variable, = updates one that already exists.
Go’s = does not produce a value. In languages like C, the expression a = 5 returns 5, so you can write if (a = 5) by mistake. Go forbids this: an assignment is a statement, not an expression. If you accidentally type if x = getValue() the compiler stops with an error. This design eliminates a whole class of subtle bugs.
Compound Assignment Operators
When you need to apply an arithmetic operation to a variable and store the result back into the same variable, you can use a compound assignment. Instead of writing x = x + 2, you write x += 2. Go provides five compound operators for arithmetic: +=, -=, *=, /=, and %=. Each one reads the current value, performs the arithmetic with the right-hand operand, and writes the result back to the left-hand variable.
package main
import "fmt"
func main() {
total := 0
total += 5 // total becomes 5
total -= 2 // total becomes 3
total *= 4 // total becomes 12
total /= 3 // total becomes 4
total %= 3 // total becomes 1
fmt.Println(total) // 1
}
The code above is functionally identical to writing the longer form each time. The compiler treats x += y exactly like x = x + y, so there is no performance difference. The main benefit is less repetition, which makes the intent clearer once you are used to reading the shorthand.
Integer division with /= truncates toward zero, exactly like the / operator. If you divide 5 /= 2, the result is 2, not 2.5. For floating-point variables, /= preserves the fractional part.
Integer Division Truncation:
When using /= on integer types, the result is always an integer. x /= y for ints discards any remainder without warning. If you need a precise quotient, first convert to float64 and perform a regular division, then assign. Forgetting this is a common source of off-by-one or rounding errors in accumulation loops.
The modulus assignment %= works only on integers. The right-hand operand must not be zero, because division by zero triggers a runtime panic, exactly as with /. This is the same panic that occurs with the ordinary / and % operators.
Bitwise Compound Operators Exist:
Go also provides &=, |=, ^=, <<=, and >>= for bitwise and shift operations. They follow the same shorthand pattern but are covered in detail under Bitwise and Shift Operators. Everything on this page about the mechanics of compound assignment applies to them as well.
Multiple Assignment
Go allows you to assign multiple values to multiple variables in a single statement by separating the items with commas.
x, y, z := 1, 2, 3 // short declaration with multiple values
x, y = y, x // swap two values
result, err := someFunc() // capture both return values
The critical rule is that all right-hand expressions are evaluated before any assignments happen. This is what makes swapping work: y and x are read while they still hold their original values, then the writes happen. The statement x, y = y, x completes without a temporary variable because Go effectively does the evaluation phase first.
a, b := 10, 20
a, b = b, a
fmt.Println(a, b) // 20 10
Multiple assignment also appears with function calls that return more than one value. The number of variables on the left must match the number of values on the right, or the compiler will complain.
Swap Without Temporary Variables:
If you've written a swap using three lines and a temporary variable in the past, Go's multiple assignment lets you collapse it to one clear line. The generated code is still safe — the compiler ensures the evaluation order produces the correct result.
When you combine multiple assignment with the short variable declaration :=, at least one variable on the left must be new to the current scope. The others can be existing variables, and they will just be reassigned.
f, err := os.Open("file.txt") // f and err are new
n, err := f.Read(buf) // n is new, err is reassigned (no new variable needed for err)
If you try to use := when every variable on the left already exists, you get no new variables on left side of :=. In that case, switch to plain =.
var x int
x := 5 // compile error: no new variables
x = 5 // correct
Short Declaration Requires a New Variable:
The rule "at least one new variable" trips up many newcomers. When you're working in a function and you want to reassign several variables at once, you might reach for := out of habit. If every name is already declared, the compiler blocks you. The fix is to use = for that line.
Multiple assignment with = works the same way: all right-hand expressions are evaluated first. This includes function calls, index expressions, and pointer dereferences — everything on the right completes before anything on the left is updated. The specification guarantees this evaluation order, so you can rely on it even when the expressions have side effects.
i := 0
arr := [3]int{10, 20, 30}
arr[i], i = arr[1], 2 // arr[0] becomes 20, i becomes 2
fmt.Println(arr[0], i) // 20 2
In this example, arr[1] is read while i is still 0, and the assignment to i does not affect the index used for arr[i]. The evaluation order is left-to-right for the right-hand expressions, but the key point is that no assignment starts until all evaluations finish.
Summary
Go’s assignment operators go beyond simply storing a value. The basic = is a pure statement that never leaks a result into surrounding expressions, which prevents an entire category of bugs common in C-family languages. The compound operators +=, -=, *=, /=, and %= are syntactic conveniences that make accumulation logic more readable without changing the runtime behavior. Multiple assignment, together with the guarantee that all right-hand expressions finish first, lets you swap values, unpack multi-return functions, and update several variables atomically from the language’s perspective.