Scala 变量

变量是一种使用方便的占位符,用于引用计算机内存地址,变量创建后会占用一定的内存空间。

基于变量的数据类型,操作系统会进行内存分配并且决定什么将被储存在保留内存中。因此,通过给变量分配不同的数据类型,你可以在这些变量中存储整数,小数或者字母。

变量声明

在学习如何声明变量与常量之前,我们先来了解一些变量与常量。

  • 变量: 在程序运行过程中其值可能发生改变的量叫做变量。如:时间,年龄。
  • 常量:在程序运行过程中其值不会发生变化的量叫做常量。如:数值 3,字符'A'。

在 Scala 中,使用关键词 "var" 声明变量,使用关键词 "val" 声明常量。

不可变变量 (val):

  • 使用 val 关键字声明的变量是不可变的,即一旦赋值后,其值不能再被改变。
  • 类似于 Java 中的 final 变量。

可变变量 (var):

  • 使用 var 关键字声明的变量是可变的,其值可以在程序的生命周期内多次改变。
  • 类似于 Java 中的普通变量。

声明变量实例如下:

var myVar : String = "Foo"
var myVar : String = "Too"

以上定义了变量 myVar,我们可以修改它。

声明常量实例如下:

val myVal : String = "Foo"

以上定义了常量 myVal,它是不能修改的。如果程序尝试修改常量 myVal 的值,程序将会在编译时报错。


变量类型声明

变量的类型在变量名之后等号之前声明。定义变量的类型的语法格式如下:

var VariableName : DataType [=  Initial Value]

或

val VariableName : DataType [=  Initial Value]

实例

object VariableExample {
  def main(args: Array[String]): Unit = {
    // 声明不可变变量
    val immutableVariable: Int = 10
    println(s"Immutable Variable: $immutableVariable")

    // 声明可变变量
    var mutableVariable: Int = 20
    println(s"Mutable Variable: $mutableVariable")

    // 修改可变变量的值
    mutableVariable = 30
    println(s"Updated Mutable Variable: $mutableVariable")

    // 不可变变量不能被重新赋值,会导致编译错误
    // immutableVariable = 15 // Uncommenting this line will cause a compilation error
  }
}

以上代码执行输出结果为:

Immutable Variable: 10
Mutable Variable: 20
Updated Mutable Variable: 30

变量命名规范

合法字符

  • 变量名必须以字母(A-Z 或 a-z)或下划线(_)开头。
  • 后续字符可以是字母、数字(0-9)或下划线。
  • 变量名不能是Scala的关键字。

驼峰命名法

  • 变量名通常采用驼峰命名法,即第一个单词以小写字母开头,后续单词的首字母大写。
  • 例如:myVariableName, userAge, accountBalance

避免使用单字符变量名

  • 除了常见的计数器变量(如i, j, k)外,应尽量避免使用单字符变量名,以提高代码的可读性。

有意义的变量名

  • 变量名应能清晰地表达其用途或含义,避免使用模糊或无意义的名称。
  • 例如:val age: Int = 25 优于 val a: Int = 25

Scala特有命名规范

  • 尽量不要使用以下划线开头的变量名,这通常用于标识内部或私有变量。
  • 可以使用字母和符号的组合来命名函数和方法,但这在变量命名中很少见。
  • 避免使用类似运算符的符号组合(如++--)作为变量名,这会使代码难以阅读和理解。

变量类型引用

在 Scala 中声明变量和常量不一定要指明数据类型,在没有指明数据类型的情况下,其数据类型是通过变量或常量的初始值推断出来的。

所以,如果在没有指明数据类型的情况下声明变量或常量必须要给出其初始值,否则将会报错。

  • 显式类型声明:明确指定变量的类型。
  • 类型推断:省略类型声明,由编译器推断类型。

Scala 的类型推断机制可以自动确定变量的类型,因此我们可以省略类型声明:

val inferredInt = 42  // 编译器推断为 Int
val inferredDouble = 3.14  // 编译器推断为 Double
val inferredString = "Hello, Scala!"  // 编译器推断为 String
val inferredBoolean = true  // 编译器推断为 Boolean

类型推断使代码更加简洁,但在复杂场景中,显式声明类型可以避免混淆。

显式类型声明时,在变量名后跟上冒号和数据类型:

val explicitInt: Int = 42
val explicitDouble: Double = 3.14
val explicitString: String = "Hello, Scala!"
val explicitBoolean: Boolean = true

显式声明有助于提高代码的可读性和维护性,特别是在类型不容易推断或容易混淆的情况下。

实例

object VariableTypesExample {
  def main(args: Array[String]): Unit = {
    // 显式类型声明
    val explicitInt: Int = 42
    val explicitDouble: Double = 3.14
    val explicitString: String = "Hello, Scala!"
    val explicitBoolean: Boolean = true

    // 类型推断
    val inferredInt = 42  // 编译器推断为 Int
    val inferredDouble = 3.14  // 编译器推断为 Double
    val inferredString = "Hello, Scala!"  // 编译器推断为 String
    val inferredBoolean = true  // 编译器推断为 Boolean

    // 可变变量
    var mutableInt: Int = 10
    println(s"Initial mutableInt: $mutableInt")
    mutableInt = 20  // 修改变量值
    println(s"Updated mutableInt: $mutableInt")

    // 输出所有变量
    println(s"Explicit Int: $explicitInt")
    println(s"Explicit Double: $explicitDouble")
    println(s"Explicit String: $explicitString")
    println(s"Explicit Boolean: $explicitBoolean")

    println(s"Inferred Int: $inferredInt")
    println(s"Inferred Double: $inferredDouble")
    println(s"Inferred String: $inferredString")
    println(s"Inferred Boolean: $inferredBoolean")
  }
}

以上代码执行输出结果为:

Initial mutableInt: 10
Updated mutableInt: 20
Explicit Int: 42
Explicit Double: 3.14
Explicit String: Hello, Scala!
Explicit Boolean: true
Inferred Int: 42
Inferred Double: 3.14
Inferred String: Hello, Scala!
Inferred Boolean: true

Scala 多个变量声明

在 Scala 中,可以同时声明多个变量。这不仅可以让代码更加简洁,还可以保证多个变量在同一行声明时的相关性。

Scala 中,可以使用逗号分隔、元组解构和 for 推导式等方法同时声明多个变量。

可以在一行中使用逗号分隔声明多个变量:

val xmax, ymax = 100  // xmax, ymax都声明为100

实例

object MultipleVariables {
  def main(args: Array[String]): Unit = {
    // 同时声明多个不可变变量
    val a, b, c: Int = 5
    println(s"a: $a, b: $b, c: $c")

    // 同时声明多个可变变量
    var x, y, z: Int = 10
    println(s"x: $x, y: $y, z: $z")

    // 修改可变变量的值
    x = 20
    y = 30
    z = 40
    println(s"Updated x: $x, y: $y, z: $z")
  }
}

如果方法返回值是元组,我们可以使用 val 来声明一个元组:

scala> val pa = (40,"Foo")
pa: (Int, String) = (40,Foo)

实例

object TupleDestructuring {
  def main(args: Array[String]): Unit = {
    // 使用元组解构同时声明多个变量
    val (a, b, c) = (1, 2, "hello")
    println(s"a: $a, b: $b, c: $c")

    // 使用元组解构同时声明多个可变变量
    var (x, y, z) = (10, 20, "world")
    println(s"x: $x, y: $y, z: $z")

    // 修改可变变量的值
    x = 30
    y = 40
    z = "Scala"
    println(s"Updated x: $x, y: $y, z: $z")
  }
}

使用 for 推导式声明多个变量

在 for 推导式中,可以同时声明多个变量,用于迭代和生成新集合。

实例

object ForComprehension {
  def main(args: Array[String]): Unit = {
    // 同时声明多个变量用于迭代
    val numbers = List((1, "one"), (2, "two"), (3, "three"))
    for ((number, word) <- numbers) {
      println(s"Number: $number, Word: $word")
    }

    // 使用 for 推导式生成新集合
    val newNumbers = for {
      (number, word) <- numbers
    } yield (number * 2, word.toUpperCase)

    println(s"New Numbers: $newNumbers")
  }
}