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

时间:2019-04-17 07:26:57

标签: scala syntax

我想了解以下内容的机制:

 val List(x) = Seq(1 to 10)

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

4 个答案:

答案 0 :(得分:7)

该机制称为模式匹配

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

这也可以理解:

for{
 People(name, firstName) <- peoples
} yield s"$firstName $name"

以您的示例为例:

val List(x) = Seq(1 to 10)

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

如果您确实有一个包含多个元素的列表,则会抛出异常

val List(x) = (1 to 10).toList // -> ERROR: undefined

因此正确的模式匹配为:

val x::xs = (1 to 10).toList

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

答案 1 :(得分:6)

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

setTimeout(() => click$.next(testPromise));

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

Range

val List(x) = Seq(1 to 10) 被分配给该x对象。

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

List

仅当右侧的表达式是包含单个元素的(1 to 10).toList 的实例时,模式List(x)才会匹配。它不会与空的List或具有多个元素的List匹配。

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

答案 2 :(得分:5)

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

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

答案 3 :(得分:3)

您可以想到

val <pattern> = <value>
<next lines>

<value> match {
  case <pattern> => 
    <next lines>
}

仅当<pattern>只是变量或具有类型的变量时,这不会发生。