Scala def、var 和 val 怎么用?有什么区别?

文章导读
Previous Quiz Next Scala 中的关键字 var、val 和 def 用于声明和使用变量、常量以及方法。var 是一个可以改变其值的变量,因此它是 mutable,var 的值可以被重新赋值。而 val 用于声明常量。一旦赋值,val 的值就不能改变,
📋 目录
  1. 可变变量 (var)
  2. 不可变变量 (val)
  3. 方法 (def)
  4. 惰性值
  5. 变量类型推断
  6. 多重赋值
  7. Scala 中 def、var 和 val 的区别
  8. 总结
A A

var、val 和 def 关键字的区别



Previous
Quiz
Next

Scala 中的关键字 varvaldef 用于声明和使用变量、常量以及方法。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 可用于值的延迟初始化。
  • 因此它提供了一种高效处理昂贵计算的方式。