斯卡拉模式匹配之谜

时间:2015-03-17 08:45:09

标签: scala pattern-matching

这是我尝试Scala中99个问题的第3个问题(P03)(http://aperiodic.net/phil/scala/s-99/):

import scala.annotation._

// Find the nth element of a list.
// nth(2, List(1, 1, 2, 3, 5, 8)) = 2

object P03 {
  @tailrec def nth[A](n: Int, ls: List[A]): A = (n, ls) match {
    case (0, h :: t :: Nil) => h
    case (n, _ :: t)        => nth(n - 1, t)
    case _                  => println(n); throw new IllegalArgumentException
}

这个谜是这段代码打印-4并抛出IllegalArgumentException

解决方案当然是将第一个模式更改为:

case (0, h :: _) => h

现在打印出正确答案2

问题是为什么?什么是微妙的区别:

case (0, h :: t :: Nil) => h

&安培;

case (0, h :: _) => h

谢谢!

1 个答案:

答案 0 :(得分:4)

区别在于h :: t :: Nil仅匹配包含两个元素的列表(htNil是列表末尾的标记(I&#39 ; m不是100%肯定它是确切的命名法))而h :: _匹配每个非空列表,即一个至少包含一个元素的列表,如果你检查::类你&# 39;见:

final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B]

其中有一个头部和一个尾部,第一个是列表的第一个元素,第二个是其余元素,匹配h :: t :: Nil表示获取列表的第一个元素,而不是尾部的第一个元素然后应该有Nilh :: _上的匹配意味着获得头部,然后只要有头脑,你就不会关心什么。