我在这里遇到了99个scala问题(http://aperiodic.net/phil/scala/s-99/p03.scala)的问题,我试图弄清楚它是如何工作的。我对Scala很新。我能够使用模式匹配和递归的类似解决方案完成此挑战,但是我没有考虑匹配中的列表。我的代码如下:
def nth[A](k: Int, l: List[A]): A = k match {
case 0 => l.head
case _ => nth(k-1, l.drop(1))
}
这似乎完成了这项工作。但是,如果列表为Nil,则不会检查错误。 99 scala问题提供的解决方案是:
def nthRecursive[A](n: Int, ls: List[A]): A = (n, ls) match {
case (0, h :: _ ) => h
case (n, _ :: tail) => nthRecursive(n - 1, tail)
case (_, Nil ) => throw new NoSuchElementException
}
我不明白的是
case(0, h:: _ )
和
case(n, _ :: tail)
作者在这做什么?我理解::将左侧的任何内容添加到右侧的开头,但我不确定究竟发生了什么。谁能开导我?
谢谢!
答案 0 :(得分:2)
::运算符用于提取头部和列表的其余部分(尾部)。
下面:
case(0, h :: _ )
只有头部是相关的,所以尾部没有参考。
在这里:
case(n, _ :: tail)
只有尾部是相关的,所以头部没有得到参考。
您也可以使用:
case(0, head :: tail)
case(n, head :: tail)
(即给两个部分一个参考)并得到完全相同的结果。
答案 1 :(得分:1)
基本上,它是模式匹配表达式。这就是Scala模式匹配如此强大的原因,因此我们可以放弃一些像Java这样的重型访问者模式(在本主题之外)。
一个简单的例子:
case class User(name: String, age: Int)
def doStuff(user: User) = user match {
case User(_, age) if age > 100 => println("Impossible!")
case User(name, _) => println("hello " + name)
}
在这种情况下,_ :: tail只是意味着我想获得尾部的引用。