Scala模式匹配混乱

 2021-04-27 

Scala pattern-matching confusion

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

1个

1
2
3
4
5
6
7
8
9
10
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个

1
2
3
4
5
6
7
8
9
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)

原因是类型++的对象上没有unapply方法。 ::起作用的原因是因为它实际上是在幕后:

1
2
3
4
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
}

来源

这导致如何在Scala中实现模式匹配。它使用提取器(或此处),这些提取器基本上是包含unapply方法的对象,该方法默认情况下与case类一起提供。


在第二种情况下,++不用于取消应用。您希望提取器::分解列表。

这里很好的解释。

1
2
3
4
5
6
7
8
9
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


++是对列表对象的一种方法。我认为您想要:

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