Scala 学习 - 函数及函数的定义

函数定义

值类型和返回值类型都定义在值的后面或方法名的后面,用冒号分隔开。

方法体最后一行是默认返回值,不需写 return

def add(a: Int, b: Int): Int = {
a + b // return 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_) // print 123
println(password()) // print 123
println(password) // print 123
}

无参数的函数定义就相当于在定义一个变量,反过来,定义变量或常量也就相当于是在定义一个无参数的函数,可在花括号里写入各种表达式。

您甚至还可以这样写:

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))	// 9.0
println(speed(10, 90)) // 0.1111111111111111
println(speed(10, 90, verbose = true)) // distance: 10.0 / time: 90 is 0.1111111111111111
// 0.1111111111111111

可变参数

可变参数在很多语言里面都有实现,本质上就是数组,只不过在 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))	// WrappedArray(1, 2, 3, 4, 5, 6)
println(sum(1, 2, 3, 4, 5, 6)) // 21

表达式

条件表达式

val password_ : String = if (true) "123" else "234"

if 是直接可以作为返回值的,类似的还有 try catchmatch case 等。

循环表达式

左闭右闭区间:

for (i <- 0 to 10) {
print(s"$i ") // 0 1 2 3 4 5 6 7 8 9 10
}

左闭右开区间:

for (i <- 0 until 10) {
print(s"$i ") // 0 1 2 3 4 5 6 7 8 9
}

步长:

for (i <- 0 until(10, 2)) {
print(s"$i ") // 0 2 4 6 8
}

for (i <- 0 to(10, 2)) {
print(s"$i ") // 0 2 4 6 8 10
}

加上条件:

for (i <- 0 until 10 if i % 2 == 1) {
print(s"$i ") // 1 3 5 7 9
}

上述代码也可以写成类似:

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
}
// 11 10 9 8 7 6 5 4 3 2 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 ")
}

// output:
// hello world will be destroyed null
// hello world will be destroyed null
// hello world will be destroyed null_str

从上述代码的运行结果,可以看出,对于 foreach 的普通调用,使用圆括号或是花括号,效果是一样的,只是前者传入的是匿名函数,后者传入的是匿名方法体;而第三种使用的是 Pattern matching,将在以后详细介绍,可以暂时理解为增强版的 switch case


   转载规则


《Scala 学习 - 函数及函数的定义》 Harbor Zeng 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
凸优化基础,本科生能看得懂的极限水平 凸优化基础,本科生能看得懂的极限水平
此篇学习笔记大多数为网络搬运+自己的理解,笔者学历不高,水平有限,就是给的多。此文所需的数学知识已经达到了笔者浅薄的认知极限。 1. 判定凸集,以及凸函数 凸集定义[1][2] Convex set 俗话定义:例如立方体、球体和圆形这样的没有凹痕和中空的集合就是凸集,月牙形不是凸集。 具体定义:在欧式空间中,凸集是对于集合内的每一对点,连接该对点的直线段上的每个点也都在该集合内。 抽象定义:凸
2020-07-19
下一篇 
Scala 学习 - 项目的创建 Scala 学习 - 项目的创建
前言 能来看这个系列教程的人,我假设您是要使用 scala 进军大数据,消息中间件,机器学习开发领域的人,对 Java 及其生态框架,比如 Maven 等已经比较熟悉,平时开发使用 Intellij IDEA,没有人会使用 javac 或者 scalac 进行大项目的管理,没有人会使用 vscode 进行 Java 项目的开发吧,所以废话不多说,直接新建项目。 Scala 插件 使用 Inte
2020-07-04
  目录