函数定义
值类型和返回值类型都定义在值的后面或方法名的后面,用冒号分隔开。
方法体最后一行是默认返回值,不需写 return
def add(a: Int, b: Int): Int = { a + b }
|
方法体如果是一个表达式,可以省略花括号:
def add(a: Int, b: Int): Int = a + b
|
变(常)量和函数的模糊边界
val password_ = "123" def password(): String = "123"
def main(args: Array[String]): Unit = { println(password_) println(password()) println(password) }
|
无参数的函数定义就相当于在定义一个变量,反过来,定义变量或常量也就相当于是在定义一个无参数的函数,可在花括号里写入各种表达式。
您甚至还可以这样写:
val password_ : String = { password() }
|
if
作为一个整体返回值
val password_ : String = { if (true) { "123" } else { "234" } }
|
写成一行的表达式
val password_ : String = if (true) "123" else "234"
|
或
val password_ : String = password()
|
甚至是:
val password_ : String = password
|
最终的 main 函数中,输出都是相同的结果。
在 scala 中,password
是在调用无参的 password 方法,而不是操作该方法的引用。
默认参数
像 python 一样,scala 支持命名参数。
举一个计算速度的例子,当 verbose
为 true 时,输出额外信息。
代码中的 $ 代表字符串内变量插值。
def speed(distance: Double, time: Double, verbose: Boolean = false): Double = { val speed = distance / time if (verbose) println(s"distance: $distance / time: $time is $speed") speed }
|
println(speed(time = 10, distance = 90)) println(speed(10, 90)) println(speed(10, 90, verbose = true))
|
可变参数
可变参数在很多语言里面都有实现,本质上就是数组,只不过在 scala 里面叫做 Seq
全称 Sequence。
def varsNumber(numbers: Int*): Seq[Int] = numbers
|
def sum(numbers: Int*): Int = numbers.sum
|
println(varsNumber(1, 2, 3, 4, 5, 6)) println(sum(1, 2, 3, 4, 5, 6))
|
表达式
条件表达式
val password_ : String = if (true) "123" else "234"
|
if
是直接可以作为返回值的,类似的还有 try catch
,match case
等。
循环表达式
左闭右闭区间:
for (i <- 0 to 10) { print(s"$i ") }
|
左闭右开区间:
for (i <- 0 until 10) { print(s"$i ") }
|
步长:
for (i <- 0 until(10, 2)) { print(s"$i ") }
for (i <- 0 to(10, 2)) { print(s"$i ") }
|
加上条件:
for (i <- 0 until 10 if i % 2 == 1) { print(s"$i ") }
|
上述代码也可以写成类似:
for (i <- 0.to(10, 2)) { print(s"$i ") }
|
的形式 (0.to(10, 2)
),那是因为在 scala 中,无参函数或单参调用可以省略 .
和 ()
,所以在 scala 中,所有操作符的定义,背后都是函数的定义,比如 +
可以写成
def add(a: Int, b: Int): Int = a.+(b)
|
while 循环:
var a = 11 while (a > 0) { print(s"$a ") a -= 1 }
|
foreach 循环:
在 Java 8 里面有函数式编程的经验的同学,可能更容易理解以下代码里 foreach
的使用:
val seqOfString = Seq("hello", "world", "will", "be", "destroyed", null)
seqOfString.foreach(str => print(s"$str ")) seqOfString.foreach { str => print(s"$str ") }
println()
seqOfString.foreach { case null => print("null_str") case str => print(s"$str ") }
|
从上述代码的运行结果,可以看出,对于 foreach
的普通调用,使用圆括号或是花括号,效果是一样的,只是前者传入的是匿名函数,后者传入的是匿名方法体;而第三种使用的是 Pattern matching,将在以后详细介绍,可以暂时理解为增强版的 switch case
。