在Scala中的赋值运算符两侧实例化对象;它是如何工作的

Sti*_*ijn 4 syntax scala

我想了解以下代码背后的机制:

 val List(x) = Seq(1 to 10)
Run Code Online (Sandbox Code Playgroud)

该机制的名称是什么?这与类型转换相同吗,还是发生了其他情况?(在Scala 2.11.12中测试。)

pme*_*pme 7

该机制称为模式匹配

这是官方文档:https : //docs.scala-lang.org/tour/pattern-matching.html

这也适用于理解:

for{
 People(name, firstName) <- peoples
} yield s"$firstName $name"
Run Code Online (Sandbox Code Playgroud)

以您的示例为例:

val List(x) = Seq(1 to 10)
Run Code Online (Sandbox Code Playgroud)

x是该列表的内容-在您的情况下Range 1 to 10(您有一个包含一个元素的列表)。

如果确实有一个包含多个元素的列表,则将引发异常

val List(x) = (1 to 10).toList // -> ERROR: undefined
Run Code Online (Sandbox Code Playgroud)

因此正确的模式匹配将是:

val x::xs = (1 to 10).toList
Run Code Online (Sandbox Code Playgroud)

现在x是第一个元素(头),xs其余是元素(尾巴)。


Tim*_*Tim 6

我怀疑您的问题实际上是表达

Seq(1 to 10)
Run Code Online (Sandbox Code Playgroud)

这不会创建10个元素的序列,而是创建一个包含单个Range对象的序列。所以当你这样做

val List(x) = Seq(1 to 10)
Run Code Online (Sandbox Code Playgroud)

x被分配给该Range对象。

如果您想要List数字,请执行以下操作:

(1 to 10).toList
Run Code Online (Sandbox Code Playgroud)

List(x)仅当右侧的表达式是List包含单个元素的实例时,该模式才匹配。它将不匹配带有多个元素的空List或a List

在这种情况下,它之所以起作用,是因为的构造函数Seq实际上返回的实例List

  • 正确的词应该是[“ pattern”](https://www.scala-lang.org/files/archive/spec/2.11/08-pattern-matching.html),而不是“表达式”。我认为最好在这种情况下区分这两件事。 (2认同)

sen*_*vic 5

这种技术称为对象分解。Haskell提供了类似的功能。Scala使用模式匹配来实现此目的。

在这种情况下使用的方法是Seq#unapplySeq:https ://www.scala-lang.org/api/current/scala/collection/Seq.html