What the operators do
Adding 1 to a variable, or subtracting 1 from it, happens constantly: counting items, moving through a list, counting down. Go has two operators for this. ++ is the increment operator and -- is the decrement operator:
number := 10
number++ // short for number += 1
fmt.Println(number) // 11
number-- // short for number -= 1
fmt.Println(number) // 10
They work on any numeric variable, not only on integers: a float64 holding 1.5 becomes 2.5 after ++.
In Go, ++ and -- are statements
This is the main difference between Go and several other languages. In Go, number++ is a complete statement that changes the variable. It does not produce a value, so it can't appear inside a larger expression. There is also only the postfix form, with the operator after the name:
number := 10
number++ // valid
// oldNumber := number++ // does not compile
// ++number // does not compile
// fmt.Println(number++) // does not compile
Each of the commented lines is a syntax error (for example, unexpected ++ at end of statement). The design is deliberate: with no value and no prefix form, there is no question of whether an expression sees the old or the new value, and no confusing expressions such as i++ + ++i.
Old value or new value: do it in two statements
When you need to keep a value from before or after the change, write two statements, in the order you need.
Store the old value, then increment
number := 10
oldNumber := number
number++
fmt.Println(oldNumber) // 10
fmt.Println(number) // 11
The copy is made before the change, so it keeps 10.
Increment, then store the new value
number := 10
number++
newNumber := number
fmt.Println(newNumber) // 11
fmt.Println(number) // 11
Here the increment comes first, so the copy gets 11. The only difference between the two snippets is the order of the two lines, and that order decides which value you capture.
The lesson's exercise
The exercise walks through all of these cases with one variable:
- Create
numberwithnumber := 18. It is anint. - Increment it with
number++. It is now 19. - Capture the old value.
post := numbercopies 19, and thennumber++raisesnumberto 20. The copy stays 19. - Increment first, then capture. After
number++,numberis 21, andpre := numbercopies 21. - Decrement it with
number--to bringnumberdown to 20.
number := 18
number++
post := number
number++
number++
pre := number
number--
Adding fmt.Println(number, post, pre) at the end prints 20 19 21. This matches the steps above: post is the value before the second increment, pre is the value after the third, and number ends one lower than pre.
In a program of your own, Go rejects a variable that is declared and never read: post := number with no later use fails with post declared and not used. Printing the values, as above, uses them and also shows what each step did, which is the quickest way to check your reasoning about old and new values.
Where you will use ++ and --
The most common place is the loop. Go has a single loop keyword, for, and the increment is usually the last part of its header:
for i := 0; i < 3; i++ {
fmt.Print(i, " ")
}
fmt.Println()
This prints 0 1 2 . Each pass through the body is followed by i++, which moves the counter on until the condition i < 3 fails.
Common mistakes and gotchas
- Using the result.
x := n++andfmt.Println(n++)do not compile. Make the change on its own line. - Writing
++n. There is no prefix form in Go. - Capturing in the wrong order. Copying before the increment gives the old value; copying after gives the new one.
- Using it on a constant or a non-numeric variable. The operand must be a numeric variable that can be assigned to.
- Forgetting that it changes the variable. Unlike
n + 1, which only computes a value,n++modifiesnitself.
Key takeaways
x++is short forx += 1andx--is short forx -= 1.- In Go they are statements, not expressions, and only the postfix form exists.
- To keep the value before or after a change, copy it on a separate line, before or after the
++. - The usual place for
i++is the header of aforloop.