【问题标题】:Instantiating objects on both sides of assignment operator in Scala; how does it work在 Scala 中实例化赋值运算符两侧的对象;它是如何工作的
【发布时间】:2019-04-17 07:26:56
【问题描述】:

我想了解下面这行背后的机制:

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

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

【问题讨论】:

    标签: scala syntax


    【解决方案1】:

    该机制称为模式匹配

    这里是官方文档: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 是其余元素(尾部)。

    【讨论】:

    • 感谢您的回答。该机制在模式匹配上下文中对我来说很有意义,但我仍然不是 100% 确定我应该如何阅读帖子中的代码行。我也不明白为什么在运行上面的行之后,x的类型是scala.collection.immutable.Range.Inclusive,而不是List[scala.collection.immutable.Range.Inclusive]
    【解决方案2】:

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

    Seq(1 to 10)
    

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

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

    x 已分配给该 Range 对象。

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

    (1 to 10).toList
    

    模式 List(x) 仅在右侧的表达式是包含单个元素的 List 的实例时才会匹配。它不会匹配空的List 或具有多个元素的List

    在这种情况下它恰好可以工作,因为Seq 的构造函数实际上返回了List 的一个实例。

    【讨论】:

    • 这对我来说很有意义,但我还是不太明白。例如,为什么val List(x) = Seq(1 to 10) 运行但val List(x) = Seq(1, 2) 抛出MatchError
    • 因为List(x) 是匹配List 的构造函数模式,它保留一个与x 匹配的元素。 Seq(1, 2) 是一个Seq,它包含两个元素,因此无法与上述模式成功匹配。
    • 如果您需要更多示例,如果您尝试val List(x, y) = Seq(1, 2)val List(x) = Seq(1),它会起作用,因为您拥有正确数量的元素。
    • 正确的词应该是"pattern",而不是“表达式”。我认为在这种情况下最好区分这两件事。
    【解决方案3】:

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

    本例中使用的方法是 Seq#unapplySeq: https://www.scala-lang.org/api/current/scala/collection/Seq.html

    【讨论】:

      【解决方案4】:

      你可以想到

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

      作为

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

      仅当&lt;pattern&gt; 只是一个变量或具有类型的变量时才会发生这种情况。

      【讨论】:

        猜你喜欢
        • 2011-02-19
        • 2013-05-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-12
        • 2016-08-20
        • 2015-10-28
        • 2012-07-15
        • 1970-01-01
        相关资源
        最近更新 更多