1.条件表达式
- 在scala中,每个表达式都有一个类型。举例来说,表达式 if(x>0) else -1 的类型为Int, 因为两个分支的类型都是Int。但对于混合表达式,如不
if (x > 0) "positive" else -1
上述表达式的类型是两个分支类型的公共超类型。在本例中,其中一个分支是java.lang.String,而另一个分支是Int。它们的公共超类型叫做Any。
如果else部分缺失了,比如:
if (x > 0) 1
那么有可能if语句没有输出值。但是在scala中,每个表达式都应该有某种值。这个问题的解决方案是引入一个Unit类,叫做 ()。此时,上面的例子相当于
if (x > 0) 1 else ()
2.块表达式和赋值
- 在Java或C++中,块语句是一个包含于{}中的语句序列。每当你需要在逻辑分支或循环中放置多个动作时,你都可以使用块语句。
- 在Scala中,{}块包含一系列表达式,其结果也是一个表达式。块中最后一个表达式的值就是块的值。
Tips:在Scala中,赋值动作本身是没有值的——或者,更严格地说,它们的值是Unit类型的。、
eg: x = y = 1 // y = 1 的值是()
val s = {r = r * n; n -= 1 } => s: Unit = ()
3.高级for循环和for推导式
- 可以以 变量->表达式 的形式提供多个生成器,用分号讲它们隔开。
eg: for (i <- 1 to 3; j <- 1 to 3) print ((10 * i + j) + " ") //将打印11 12 13 21 22 23 31 32 33
- 每个生成器都可以带一个守卫,以 if 开头的Boolean表达式:
eg: for ( i <- 1 to 3; j <- 1 to 3 if i != j) print ((10 * i + j) + " ") //将打印 12 13 21 23 31 32
Tips:在 if 之前并没有分号
- 可以使用任意多的定义,引入可以在循环中使用的变量。
eg:for ( i <- 1 to 3; from = 4 - i; j <- from to 3) print ((10 * i + j) + " ") //将打印 13 22 23 31 32 33
4.默认参数和带名参数
- 在调用某些函数时并不显示地给出所有参数值,对于这些函数可以使用默认参数
eg:def decorate(str: String, left: String = "[", right: Strin = "]") = left + str + right
这个函数有两个参数,left和right带有默认值“[”和"]"
Tips:如果相对参数的数量,给出的值不够,默认参数会从后往前逐个应用进来
也可以混用未命名参数和带名参数,只要那些未命名的参数是排在前面的即可:
eg: decorate("Hello", right = "]<<<")
5.变长参数
- 有时候,实现一个可以接受可变长度参数列表的函数会很方便。
def sum(args: Int*) = {
var result = 0
for(arg <- args) result += arg
result
}
var s = sum(1, 4, 9, 16, 25)
Tips:函数得到是一个类型为Seq的参数。如果是一个已经有值序列,则不能将它传入上述函数。
eg: val s = sum(1 to 5) //错误
如果sum函数被调用时传入的是单个参数,那么该参数必须是单个整数,而不是一个整数区间。解决这个问题的办法是告诉编译器希望这个参数被当做参数序列处理。追加:_*,就像这样:
val s = sum(1 to 5: _*) //将1 to 5 当做参数序列处理
6.过程
- Scala对于不返回值的函数有特殊的表示法。如果函数体包含在花括号当中但没有前面的=号,那么返回类型就是Unit。这样的函数被称作过程。
eg: def box(s: String) { //注意:没有=号
var border = "-" + s.length + "--\n"
println(border + "|" + s + "|\n" + border)
}