var、val 和 def 关键字的区别
Scala 中的关键字 var、val 和 def 用于声明和使用变量、常量以及方法。var 是一个可以改变其值的变量,因此它是 mutable,var 的值可以被重新赋值。而 val 用于声明常量。一旦赋值,val 的值就不能改变,因此它是 immutable。这类似于 Java 中的 final 变量,其中变量类型保持不变。def 关键字用于声明 methods。与 var 和 val 在定义时求值不同,def 在每次调用时都会被求值。本文讨论了这三个关键字。
可变变量 (var)
使用关键字 var 声明的变量是可变的,这意味着其值可以在程序执行期间改变。当你需要一个可以更新的变量时,这非常有用。
语法
var 变量的语法如下 -
var myVar: String = "Foo"
示例
object Demo {
def main(args: Array[String]) = {
var myVar: Int = 10
println(myVar)
myVar = 20
println(myVar)
}
}
将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
10 20
在这里,myVar 是一个类型为 Int 的可变变量。其值最初设置为 10,后来更改为 20。
不可变变量 (val)
使用关键字 val 声明的变量是不可变的。因此,一旦赋值,其值就不能改变。这类似于常量。
语法
val 变量的语法如下 -
val myVal: String = "Foo"
示例
object Demo {
def main(args: Array[String]) = {
val myVal: String = "Hello, Scala!"
println(myVal)
// 取消注释下一行会导致编译错误
// myVal = "New Value"
}
}
将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
Hello, Scala!
在这里,myVal 是不可变的。一旦设置为 "Hello, Scala!",就不能被重新赋值。
方法 (def)
Scala 中的方法使用 def 关键字声明。这些方法代表函数,并在每次调用时求值。
语法
声明方法的语法如下 -
def methodName(parameterList): ReturnType = { methodBody }
示例
object Demo {
def add(x: Int, y: Int): Int = x + y
def main(args: Array[String]) = {
val result = add(3, 5)
println(s"Result: $result")
}
}
将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
Result: 8
在这里,我们使用 def 关键字声明了 add 方法。add 方法接受两个整数并返回它们的和。它在每次调用时都会被求值。
惰性值
Scala 中的惰性值使用 lazy val 定义。它们的初始化会被延迟到第一次访问时才执行。这些值可用于昂贵的计算。
示例
object Demo {
lazy val lazyVal: Int = {
println("Computing lazy value")
42
}
def main(args: Array[String]) = {
println("Before accessing lazyVal")
println(lazyVal)
println(lazyVal)
}
}
将上述程序保存为 Demo.scala。使用以下命令编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
Before accessing lazyVal Computing lazy value 42 42
在这里,lazyVal 在第一次访问之前不会被计算。因此,它延迟了初始化块中的打印语句。
变量类型推断
当你为变量赋值初始值时,Scala 编译器可以根据赋值的数值推断变量的类型。这被称为变量类型推断。
语法
变量类型推断的语法如下 -
var myVar = 10 // myVar 被推断为 Int 类型 val myVal = "Hello, Scala!" // myVal 被推断为 String 类型
示例
object Demo {
def main(args: Array[String]) = {
var myVar = 10
val myVal = "Hello, Scala!"
println(myVar)
println(myVal)
}
}
将上述程序保存为 Demo.scala。使用以下命令来编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
10 Hello, Scala!
在这里,myVar 被推断为 Int 类型,myVal 被推断为 String 类型。
多重赋值
Scala 支持多重赋值。如果一个代码块或方法返回一个 tuple,则可以将该 tuple 赋值给一个 val 变量。
语法
使用多重赋值的语法如下 -
val (myVar1: Int, myVar2: String) = (40, "Foo")
示例
object Demo {
def main(args: Array[String]) = {
val (myVar1, myVar2) = (40, "Foo")
println(myVar1)
println(myVar2)
}
}
将上述程序保存为 Demo.scala。使用以下命令来编译和执行该程序。
命令
>scalac Demo.scala >scala Demo
输出
40 Foo
在这里,myVar1 和 myVar2 分别被赋值为 40 和 "Foo"。
Scala 中 def、var 和 val 的区别
下表展示了基于不同方面的 def、var 和 val 关键字的关键区别 −
| 特性 | var | val | def |
|---|---|---|---|
| 可变性 | 可变 | 不可变 | 不适用 |
| 重新赋值 | 允许 | 不允许 | 不适用 |
| 用法 | 变量 | 常量 | 方法 |
| 语法 | var x: Type = value | val x: Type = value | def methodName(params): Type |
| 求值时机 | 声明时 | 声明时 | 每次调用时 |
| 内存分配 | 声明时 | 声明时 | 每次调用时 |
| 惰性求值 | 不支持 | 通过 lazy val 支持 | 不支持 |
| 示例 | var x = 10 | val y = 20 | def add(a: Int, b: Int) = a + b |
| 类似于 | Java 中的可变变量 | Java 中的 final 变量 | Python 中的函数 |
总结
- var 用于可变变量,其值可以改变。
- val 用于不可变变量,其值不能改变。
- def 用于定义方法,每次调用时都会求值。
- lazy val 可用于值的延迟初始化。
- 因此它提供了一种高效处理昂贵计算的方式。