Adding or subtracting one
Raising a variable by 1, or lowering it by 1, is so common that many languages give it a dedicated operator, usually written ++ and --. Scala has neither. The idiomatic replacements are the augmented assignments += 1 and -= 1:
var number: Int = 10
number += 1
println(number)
number -= 1
println(number)
This prints 11, then 10. The statement number += 1 is short for number = number + 1.
Both lines need number to be a var. A val can't be reassigned, so += on it doesn't compile.
Why there is no ++
If you write number++, the compiler reports value ++ is not a member of Int. A prefix form such as ++number fails too, with Not found: ++. Neither is a Scala operator, so the compound assignment is the only short form to remember.
Post-increment and pre-increment, done by hand
In languages that have ++, the two forms differ in what the expression gives back. The postfix form returns the value from before the change, and the prefix form returns the value from after it. In Scala, number += 1 is a statement that changes the variable but gives back no useful value: its result is (), the single value of type Unit. So you can't capture the result of the increment itself, and you use two lines instead. The order of the lines gives you the same effect.
Value before the change
Read the variable first, then change it:
var number: Int = 10
val oldNumber = number
number += 1
println(oldNumber)
println(number)
This prints 10, then 11. oldNumber is a copy of the number taken before the change, so it keeps the value 10.
Value after the change
Change the variable first, then read it:
var number: Int = 10
number += 1
val newNumber = number
println(newNumber)
println(number)
This prints 11, then 11. The same idea works for decrementing: with number -= 1 in place of number += 1, both lines print 9.
The copy never changes afterwards, because an Int is a plain value, not a reference to the variable. Later changes to number don't affect oldNumber or newNumber. They are vals as well, so they can't be reassigned.
The lesson's exercise
The exercise walks through all of these ideas on one variable. Here is the value after each step:
- Create
numberwithvarand the value18. number += 1makes it19.- Copy it into
postfirst, then increment.postholds19andnumberbecomes20. - Increment again, then copy into
pre.numberbecomes21andpreholds21. number -= 1brings it back to20.
The solution:
var number = 18
number += 1
val post = number
number += 1
number += 1
val pre = number
number -= 1
Notice that the third step takes post before its increment, while pre is taken after the increment. That difference in order is the entire post-versus-pre distinction. At the end, post is 19, pre is 21 and number is 20.
Common mistakes
- Writing
number++or++number. Neither compiles in Scala. - Using
valfor the counter. The first+=fails. Usevarfor values that change. - Trying to capture the increment's result.
val k = (number += 1)stores(), not the new number. Readnumberon its own line. - Swapping the order. Copying after the increment gives the new value even when you wanted the old one.
Key takeaways
- Scala has no
++or--; use+= 1and-= 1on avar. - The compound assignment changes the variable but returns
Unit. - To get the old value, copy the variable before changing it. To get the new value, copy it after.
