这是我尝试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
谢谢!
答案 0 :(得分:4)
区别在于h :: t :: Nil
仅匹配包含两个元素的列表(h
和t
,Nil
是列表末尾的标记(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
表示获取列表的第一个元素,而不是尾部的第一个元素然后应该有Nil
,h :: _
上的匹配意味着获得头部,然后只要有头脑,你就不会关心什么。