在scala中一次分配多个变量

时间:2012-02-23 18:02:36

标签: scala

我有以下代码:

val text = "some text goes here"
val (first, rest) = text.splitAt(4)
println(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)

但这给了我一个错误:

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

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

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

3 个答案:

答案 0 :(得分:15)

Serj的回答提供了一种更好的方式来写这个,但是为了回答你关于为什么你的第二个版本不起作用的问题,你可以转到Scala specification,这可以区分变量定义分配

来自“4.2变量声明和定义”:

  

变量定义也可以有一个模式(§8.1)   左手边。变量定义var p = e,其中p是   模式以外的简单名称或名称后跟冒号和   type以val p = e的相同方式(第4.1节)进行扩展,但p中的自由名称是作为可变变量引入的,而不是值。

来自“6.15作业”:

  

对简单变量x = e的赋值的解释取决于   关于x的定义。如果x表示一个可变变量,那么   赋值将x的当前值更改为结果   评估表达式e

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

答案 1 :(得分: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)

答案 2 :(得分:9)

SerJ de SuDDeN的答案是绝对正确的,但更详细的一些细节为什么你提到的代码以它的工作方式工作。

val (a, b) = (1, 2)

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

scala> val head :: tail = 1 :: 2 :: 3 :: Nil
head: Int = 1
tail: List[Int] = List(2, 3)

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

其他一些地方可以是理解

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

或具有更高阶方法的等效符号

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