【问题标题】:Scala pattern-matching confusionScala 模式匹配混淆
【发布时间】:2014-10-22 04:29:06
【问题描述】:

我开始学习 Scala,但我不太了解模式匹配的一些行为。谁能向我解释为什么第一种情况有效,而第二种情况无效?

1

def getFirstElement(list: List[Int]) : Int = list match {
    case h::tail => h
    case _ => -1
}

Scala> getFirstElement(List(1,2,3,4))
res: Int = 1

Scala> 1 :: List(1,2)
res: List[Int] = List(1, 1, 2)

2

def getSumofFirstTwoElement(list: List[Int]): Int = list match {
    case List(a: Int, b: Int)++tail => a + b
    case _ => -1
}

<console>:11: error: not found: value ++

Scala> List(1,2) ++ List(3,4,5)
res: List[Int] = List(1, 2, 3, 4, 5)

【问题讨论】:

    标签: scala


    【解决方案1】:

    原因是++ 类型的对象上没有unapply 方法。 ::之所以起作用,是因为它在幕后是真的:

    final case class ::[B](override val head: B, private[scala] var tl: List[B]) extends List[B] {
      override def tail : List[B] = tl
      override def isEmpty: Boolean = false
    }
    

    Source

    这导致了在 Scala 中如何实现模式匹配。它使用extractors(或here),它们基本上是包含unapply 方法的对象,默认情况下由case 类提供。

    【讨论】:

    • 另外,应该注意的是,它作为 hd :: tl 工作,因为它以 : 结尾,这表示它可以以这种右关联方式使用。我开始想办法让你的 ++ 工作,但它就是不漂亮
    【解决方案2】:

    ++ 是列表对象的方法。我想你想要:

    def getSumofFirstTwoElement(list: List[Int]): Int = list match {
         case a::b::tail => a + b
         case _ => -1
    }
    

    【讨论】:

    • 这行得通。我理解 ++ 方法是列表对象的方法。为什么我不能在匹配案例模式中使用它?谢谢。
    • 正如贾斯汀所说,由于 unapply 将对象变成了它的组件。
    【解决方案3】:

    情况二,++ 不用于取消申请。您希望提取器 :: 分解列表。

    很好的解释here

    scala> def getSumofFirstTwoElement(list: List[Int]): Int = list match {
         |     case a::b::t => a + b
         |     case _ => -1
         | }
    getSumofFirstTwoElement: (list: List[Int])Int
    
    
    scala> getSumofFirstTwoElement(List(1,2,3,4))
    res0: Int = 3
    

    【讨论】:

      猜你喜欢
      • 2011-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-17
      • 2021-12-17
      • 2014-09-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多