[英]Scala Pattern Matching Enigma
這是我對Scala的99個問題( http://aperiodic.net/phil/scala/s-99/ )中的第三個問題(P03)的嘗試:
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
謝謝!
區別在於h :: t :: Nil
僅匹配具有兩個元素的列表( h
和t
, Nil
是列表結尾的標記(我不是100%確信它的確切命名)),而h :: _
匹配每個非空列表,即,至少包含一個元素的列表,如果您檢查::
類,您將看到:
final case class ::[B](private var hd: B, private[scala] var tl: List[B]) extends List[B]
其中有頭有尾,第一個是列表的第一個元素,第二個是其余的,匹配h :: t :: Nil
表示獲取列表的第一個元素,而不是尾部的第一個元素,然后是應該有一個Nil
,在h :: _
上匹配意味着要抬頭,然后只要有頭就不必理會剩下的東西。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.