What they do
Adding 1 to a variable, or taking 1 away, happens so often that Kotlin has an operator for each. ++ is the increment operator and -- is the decrement operator:
var number = 10
number++ // same as number += 1
println(number)
number-- // same as number -= 1
println(number)
11
10
The variable has to be a var, because the operators reassign it. On a val, the compiler reports 'val' cannot be reassigned. and the program doesn't run.
The most common use is a counter, a variable that goes up by one each time something happens. After var visits = 0 followed by two visits++ statements, visits is 2. The same pattern with -- counts down, for example the number of items left to process. Because the operators say exactly what they do, they are easier to read than visits = visits + 1.
Postfix and prefix forms
Both operators can be written after the variable (postfix, number++) or before it (prefix, ++number). On a line of their own, the two forms do the same thing. The difference shows only when you use the value of the expression, for example by storing it in another variable.
- Postfix increments the variable, but the expression's value is the value before the change.
- Prefix increments the variable, and the expression's value is the value after the change.
var number = 10
val oldNumber = number++
println(oldNumber)
println(number)
10
11
Postfix is the same as taking a copy of the old value, then incrementing:
val oldNumber = number
number++
The prefix form increments first and hands out the new value:
var number = 10
val newNumber = ++number
println(newNumber)
println(number)
11
11
Decrement behaves the same way. val newNumber = --number with number at 10 leaves both variables at 9, and val old = number-- would give old the value 10 and leave number at 9.
The lesson's exercise, step by step
- Create
numberwithvar, set to 18. Avalwould not work, since every later step changes it. - Apply
number++on its own line. The value becomes 19. Nothing uses the expression's value here, so the postfix and prefix forms are identical. - Store a postfix increment in
post.val post = number++givespostthe old value, 19, and thennumberbecomes 20. - Store a prefix increment in
pre.val pre = ++numberincrements first, sonumberbecomes 21 andpreis 21 as well. - Apply the prefix
--tonumber. On its own line it just lowersnumberby one, to 20.
var number = 18
number++
val post = number++
val pre = ++number
--number
After these lines, post is 19, pre is 21 and number is 20.
Gotchas
Mixing both forms in one expression
Each use of ++ changes the variable at that moment, so an expression with several of them depends on the order of evaluation. With i at 5, i++ + ++i gives 12: the postfix part contributes 5 and makes i 6, then the prefix part makes it 7 and contributes 7. Afterwards i is 7. Code like this is hard to read, so keep each increment in a statement of its own.
Assigning a postfix result back to the same variable
With n at 7, the statement n = n++ leaves n at 7. The right side evaluates to the old value and increments the variable, and then the assignment stores the old value back over the new one. The increment is lost. If you want to increment, write n++ alone.
Only on variables
The operators change a variable, so the thing they apply to must be one. Writing 5++ makes no sense, because 5 is a value and not a place that can store anything.
Int overflow
For an Int, which has 32 bits, incrementing Int.MAX_VALUE wraps around silently to -2147483648. Use a Long if a counter can grow that large.
Key takeaways
++adds 1 and--subtracts 1. They need avar.- Alone on a line, prefix and postfix are the same.
- Used as a value, postfix gives the value before the change and prefix gives the value after it.
- Keep increments in their own statements, so the code reads in one pass.