What operator precedence is
When an expression has more than one operator, Go has to decide which one to apply first. Take 1 + 2 * 3. Read left to right, you would add first and get 9. Go instead multiplies first and gets 7. The rules that settle this are called operator precedence, and every language has them. Knowing them lets you predict what a line of code prints without running it.
The rules
For the arithmetic operators, the order from strongest to weakest is:
- Parentheses
( )are always respected: whatever is inside is computed first. *,/and%(multiplication, division and remainder) come next.+and-(addition and subtraction) come last.- When operators have the same rank, Go evaluates them from left to right.
Go's full table also covers shifts, bit operators, comparisons and the logical operators && and ||. Comparisons and the logical operators rank below + and -. For arithmetic, the list above is what you need.
Worked examples
Multiplication before addition
fmt.Println(1 + 2 * 3) // 7
fmt.Println(6 - 4 / 2) // 4
fmt.Println(5 * 4 - 2 / 2) // 19
In the first line, 2 * 3 is 6, and 1 plus 6 is 7. In the second, 4 / 2 is 2, and 6 minus 2 is 4. In the third, both 5 * 4 and 2 / 2 run before the subtraction, so Go computes 20 minus 1, which is 19.
Parentheses change the order
fmt.Println((1 + 2) * 3) // 9
fmt.Println((6 - 4) / 2) // 1
fmt.Println(5 * (4 - 2) / 2) // 5
The sum or difference inside the parentheses is evaluated first, so the first line is 3 * 3. In the last line, (4 - 2) is 2, then Go goes left to right through 5 * 2 / 2: 10, then 5.
Same rank, left to right
fmt.Println(6 / 4 * 3 + 5) // 8
Division and multiplication have the same rank, so 6 / 4 runs before * 3. Both operands are integers, so 6 / 4 is 1, not 1.5. Then 1 * 3 is 3, and 3 + 5 is 8. If you wrote the multiplication first, 3 * 6 / 4 + 5 would give 9, because 18 / 4 is 4.
Nested parentheses
fmt.Println(6 / ((4 + 2) / 3)) // 3
Go works from the innermost parentheses outward: (4 + 2) is 6, then 6 / 3 is 2, and finally 6 / 2 is 3.
Remainder shares the rank of multiplication
fmt.Println(2 + 3 * 3 % 4) // 3
fmt.Println(10 - 4 % 3 * 2) // 8
In the first line, 3 * 3 is 9, then 9 % 4 is 1, and 2 + 1 is 3. In the second, 4 % 3 is 1, 1 * 2 is 2, and 10 - 2 is 8.
The lesson's exercise
The starting code prints the value of 2 + 3 * 3. Because multiplication runs first, it prints 11 (3 * 3 is 9, plus 2). The task is to make it print 15.
Ask which two numbers have to be added before multiplying by 3 to reach 15. Since 15 / 3 is 5, and 2 + 3 is 5, the addition of 2 + 3 must run first. Wrapping it in parentheses forces that:
fmt.Println((2 + 3) * 3)
Go now evaluates 2 + 3 to get 5, multiplies by 3, and prints 15.
Common mistakes and gotchas
- Reading strictly left to right. Left to right applies only between operators of the same rank.
2 + 3 * 3is 11, not 15. - Forgetting that integer division truncates. The result of
6 / 4 * 3is 3, but6 * 3 / 4is 4. Same numbers, different order, different answer. - Parentheses in the wrong place.
(2 + 3 * 3)still prints 11, because everything inside is again evaluated by the usual rules. The parentheses must surround the part you want to run first. - Unbalanced parentheses. Every
(needs a matching), or the program does not compile. - Relying on memory in long expressions. Extra parentheses never hurt:
(a * b) + cmeans the same asa * b + c, and the first form is easier to read.
Key takeaways
- Go evaluates
*,/and%before+and-. - Equal-ranked operators run from left to right.
- Parentheses override everything, and nested ones are evaluated from the inside out.
- With integers, the order of a division relative to other operators can change the result.