在scala中一次分配多个变量

use*_*043 17 scala

我有以下代码:

val text = "some text goes here"
val (first, rest) = text.splitAt(4)
println(first + " *" + rest)
Run Code Online (Sandbox Code Playgroud)

这很好.

但是,我想有两个案例,在外面定义"first"和"rest",如下所示:

val text = "some text goes here"
var (first, rest) = ("", "")
if (text.contains("z")) {
  (first, rest) = text.splitAt(4)
} else {
  (first, rest) = text.splitAt(7)
}
println(first + " *" + rest)
Run Code Online (Sandbox Code Playgroud)

但这给了我一个错误:

scala>      | <console>:2: error: ';' expected but '=' found.
         (first, rest) = text.splitAt(4)
Run Code Online (Sandbox Code Playgroud)

为什么要做错误(首先,休息)= text.splitAt(4)但不要做val(首先,休息)= text.splitAt(4)?我该怎么办?

编辑:无法重新分配val,更改为var.同样的错误

Tra*_*own 15

由Serj答案给出了写这更好的办法,但对于一个答案,你为什么你的第二个版本无法正常工作的问题,你可以去斯卡拉规范,这使得区分变量定义分配.

从"4.2变量声明和定义":

或者,变量定义可以将模式(第8.1节)作为左侧.变量定义var p = e,其中p是一个模式不是一个简单的名称或名称后面跟着冒号和类型等以相同的方式(§4.1)作为值定义扩大val p = e,所不同的是在自由名称p被引入作为可变的变量,而不是值.

从"6.15作业":

对简单变量的赋值的解释x = e取决于对的定义x.如果x表示一个可变变量,则赋值会将当前值更改为计算x表达式的结果e.

(first, rest) 这是一个模式,而不是一个简单的变量,因此它适用于变量定义,但不适用于赋值.

  • @ user1229043模式匹配存在于`match`,`for` comprehensions,`val` /`var`声明和`catch`上.没有办法同时(重新)分配多个变量. (5认同)

Ser*_*nko 13

首先val是不可改变的,所以你不能重新分配它.其次,if与Scala中的所有控制结构一样,可以返回一个值.所以,你可以这样做:

val text = "some text goes here"
val (first, rest) = if (text.contains("z")) text.splitAt(4) else text.splitAt(7)
println(first + " *" + rest)
Run Code Online (Sandbox Code Playgroud)

  • 或者更简洁一点:`val(first,rest)= text.splitAt(if(text.contains("z"))4 else 7)`. (14认同)

kir*_*uku 9

SerJ de SuDDeN的答案是完全正确的,但更多细节为什么你提到的代码按照它的工作方式工作.

val (a, b) = (1, 2)
Run Code Online (Sandbox Code Playgroud)

被称为模式匹配表达式的提取器.右侧的值与左侧的提取器匹配.这可以在Scala中的任何地方完成,并且可以具有不同的面.例如,List上的模式匹配可能看起来像

scala> val head :: tail = 1 :: 2 :: 3 :: Nil
head: Int = 1
tail: List[Int] = List(2, 3)
Run Code Online (Sandbox Code Playgroud)

在右侧,::-symbol是类List的方法,它为元素添加元素.在左侧,::-symbol是类的提取器,::是List的子类.

其他一些地方可以是理解

scala> for ((a, b) <- (1 to 3) zip (4 to 6)) println(a+b)
5
7
9
Run Code Online (Sandbox Code Playgroud)

或者使用高阶方法的等效符号

scala> (1 to 3) zip (4 to 6) foreach { case (a, b) => println(a+b) }
5
7
9
Run Code Online (Sandbox Code Playgroud)