Thinking in expressions instead of statements is what makes Scala code concise.
In Scala nearly everything is an expression with a value. if returns a value, so there's no ternary operator: val sign = if x < 0 then -1 else 1. A block { ... } (or an indented block) evaluates to its last expression. An if without else yields () when the condition is false, so its value is rarely useful.
Loops:
while cond do bodyis the imperative loop; it returnsUnit.for i <- 1 to 5 do println(i)iterates over a range or collection.1 to 5includes 5,1 until 5excludes it, andbysets a step.- Several generators and guards can be combined:
for i <- 1 to 3; j <- 1 to 3 if i != j do .... for x <- xs yield f(x)builds a new collection: a for expression. Its result type follows the input collection.
match is the other key control structure (covered in pattern matching): x match { case 1 => "one"; case _ => "many" }.
There is no break or continue keyword. Usually a collection method (find, takeWhile, exists) expresses the intent better; scala.util.boundary with break exists for the rare cases you need an early exit.
try/catch/finally is an expression too, and return is rarely used: the last expression of a method is its result.
Example
val x = -7
val sign = if x < 0 then "negative" else "non-negative"
println(sign) // negative
val total =
val a = 10
val b = 32
a + b // value of the block
println(total) // 42
var n = 1
while n < 100 do n *= 3
println(n) // 243
for i <- 1 to 3; j <- 1 to 3 if i < j do
print(s"($i,$j) ") // (1,2) (1,3) (2,3)
println()
val squares = for k <- 1 until 5 yield k * k
println(squares) // Vector(1, 4, 9, 16)
println((10 to 1 by -3).toList) // List(10, 7, 4, 1)Remember
if, blocks,match,tryandfor ... yieldall return values1 to nincludes n,1 until nexcludes itfor ... doloops for effects,for ... yieldbuilds collections
Watch out for
- Writing an
ifwithoutelseand expecting a useful value: the missing branch is().