在 Scala 中一次分配多个变量

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9418576/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-22 03:54:36  来源:igfitidea点击:

Assign multiple variables at once in scala

scala

提问by user1229043

I have the following code:

我有以下代码:

val text = "some text goes here"
val (first, rest) = text.splitAt(4)
println(first + " *" + rest)

That works fine.

这很好用。

However, I want to have two cases, defining "first" and "rest" outside, like this:

但是,我想有两种情况,在外面定义“第一”和“休息”,如下所示:

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)

But that gives me an error:

但这给了我一个错误:

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

Why is it an error to do (first, rest) = text.splitAt(4) but not to do val (first, rest) = text.splitAt(4)? And what can I do?

为什么执行 (first, rest) = text.splitAt(4) 而不是执行 val (first, rest) = text.splitAt(4) 是错误的?我能做什么?

Edit: Can't re-assign val, changed to var. Same error

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

回答by Travis Brown

The answer by Serj gives a better way of writing this, but for an answer to your question about why your second version doesn't work, you can go to the Scala specification, which makes a distinction between variable definitionsand assignments.

Serj 的答案提供了一种更好的编写方式,但是要回答关于为什么第二个版本不起作用的问题,您可以转到Scala 规范,它区分了变量定义赋值

From "4.2 Variable Declarations and Definitions":

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

Variable definitions can alternatively have a pattern (§8.1) as left-hand side. A variable definition var p = ewhere pis a pattern other than a simple name or a name followed by a colon and a type is expanded in the same way (§4.1) as a value definition val p = e, except that the free names in pare introduced as mutable variables, not values.

变量定义也可以有一个模式(第 8.1 节)作为左侧。一个变量定义var p = e,其中p是一个模式而不是一个简单的名称或一个名称后跟一个冒号和一个类型,以与值定义相同的方式(第 4.1 节)扩展val p = e,除了自由名称p作为可变变量引入,而不是值。

From "6.15 Assignments":

来自“6.15 作业”:

The interpretation of an assignment to a simple variable x = edepends on the definition of x. If xdenotes a mutable variable, then the assignment changes the current value of xto be the result of evaluating the expression e.

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

(first, rest)here is a pattern, not a simple variable, so it works in the variable definition but not in the assignment.

(first, rest)这是一个模式,而不是一个简单的变量,所以它在变量定义中起作用,但在赋值中不起作用。

回答by Sergey Passichenko

First of all valis immutable, so you can't reassign it. Second, if, like all control structures in Scala, can return a value. So, you can do it like this:

首先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)

回答by kiritsuku

SerJ de SuDDeN answer is absolutely correct but some more details why the code you mentioned works the way it works.

SerJ de SuDDeN 的回答是绝对正确的,但还有一些更多的细节,为什么你提到的代码会以这种方式工作。

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

is called an extractor of a pattern-match-expression. The value on the right side is matched to the extractor of the left side. This can be done everywhere in Scala and can have different faces. For example a pattern match on a List can look something like

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

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

On the right side the ::-symbol is a method of class List which prepends elements to it. On the left side the ::-symbol is an extractor of class ::, a subclass of List.

在右侧,::-symbol 是类 List 的一个方法,它在它前面添加了元素。左侧的::-symbol 是 class 的提取器,::是 List 的子类。

Some other places can be for-comprehensions

其他一些地方可以换领悟

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

or the equivalent notation with higher-order-methods

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

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