An expression has a value; a statement carries out an action.
Conditional Expressions: IF-ELSE
In Scala, an if / else has a value. For example: if (x > 0) 1 else -1 or val s = if (x > 0) 1 else -1 has a value of 1 or -1 , depending on the value of x .
Java and C++ have a ?: operator for this purpose: x > 0 ? 1 : -1
In Scala, every expression has a type. For example:
if (x > 0) 1 else -1 has a type of Int.
if (x > 0) "positive" else -1 has a type of Any.
if (x > 0) 1 has a type of Int or Unit(no value).
Statement Termination
if you want to have more than one statement on a single line, you need to separate them with semicolons, else semicolons are optional. For example
if (n > 0) { r = r * n; n -= 1 }
Block Expressions and Assignments
In Scala, a { } block contains a sequence of expressions, and the result is also an expression. The value of the block is the value of the last expression. For example: val distance = { val dx = x - x0; val dy = y - y0; sqrt(dx * dx + dy * dy) }. The value of the { } block is the last expression, shown here in bold.
However, since in Scala, assignments have no value or a Unit value, so a block that ends with an assignment statement, such as { r = r * n; n -= 1 } has a Unit value. Therefore, x = y = 1 is wrong!
Input and Output
scala> println("Answer: " + 42) Answer: 42
Loops
WHILE:
FOR: traverse Integers
where 1 to n equals to 1.to(n). For a Scala collection, such as a Range , the loop makes i assume each value in turn.
FOR: traverse Strings
OR
In Scala, loops are not used as often as in other languages. You can often process the values in a sequence by applying a function to all of them, which can be done with a single method call.
Advanced for Loops and for Comprehensions
(1)multipe generators in FOR separated by semicolons.
scala> for (i <- 1 to 3; j <- 1 to 3) print((10 * i + j) + " ") 11 12 13 21 22 23 31 32 33
(2)Each generator can have a guard.
scala> for (i <- 1 to 3; j <- 1 to 3 if i != j) print((10 * i + j) + " ")//if i!=j is a guard 12 13 21 23 31 32
(3)You can have any number of definitions, introducing variables that can be used inside the loop.
scala> for (i <- 1 to 3; from = 4 - i; j <- from to 3) print((10 * i + j) + " ") 13 22 23 31 32 33
(4)If starts with yield , then the loop constructs a collection of values.
scala> for (i <- 1 to 10) yield i % 3 res36: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 0, 1, 2, 0, 1, 2, 0, 1)
This type of loop is called a for comprehension. The generated collection is compatible with the first generator. Like
scala> for (c <- "Hello"; i <- 0 to 1) yield (c + i).toChar res37: String = HIeflmlmop scala> for (i <- 0 to 1; c <- "Hello") yield (c + i).toChar res38: scala.collection.immutable.IndexedSeq[Char] = Vector(H, e, l, l, o, I, f, m, m, p)
Functions
Scala has functions in addition to methods. A method operates on an object【1.to(0)这里的to就operates on a Int object】, but a function doesn’t【a function 像java中的static 方法,遵循functional programming的思想】.
(1)You must specify the types of all parameters: def abs(x: Double) = if (x >= 0) x else -x
(2)The last expression of the block becomes the value that the function returns:
(3)If the function is a recursive function, you must specify the return type: def fac(n: Int): Int = if (n <= 0) 1 else n * fac(n - 1). Otherwise Scala compiler couldn’t verify that the type of n * fac(n - 1) is an Int.
Default and Named Arguments(参数默认值)
def decorate(str: String, left: String = "[", right: String = "]") =left + str + right
You can also specify the parameter names when you supply the arguments:decorate(left = "<<<", str = "Hello", right = ">>>"). Note that the named arguments need not be in the same order as the parameters.
Variable Arguments: the number of arguments is not fixed
def sum(args: Int*) = {
var result = 0
for (arg <- args) result += arg
result
}
You can call this function with as many arguments as you like: val s = sum(1, 4, 9, 16, 25)
If you already have a sequence of values, you cannot pass it directly to such a function: val s = sum(1 to 5) // Error. But
val s = sum(1 to 5: _*) // Consider 1 to 5 as an argument sequence
Procedures
Procedure differentiates from function in that a procedure has no = symbol.
You call it for its side effect. For example, the following procedure prints a string inside a box, like
-------
|Hello|
-------
def box(s : String) { // Look carefully: no =
val border = "-" * s.length + "--
"
println(border + "|" + s + "|
" + border)
}
Lazy Values
When a val is declared as lazy , its initialization is deferred until it is accessed for the first time. For example,
lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString
If the program never accesses words , the file is never opened.
You can think of lazy values as halfway between val and def . Compare
val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated as soon as words is defined
lazy val words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated the first time words is used
def words = scala.io.Source.fromFile("/usr/share/dict/words").mkString // Evaluated every time words is used