使用模式匹配确定列表的lat元素的代码:
@tailrec
def last_rec[A](list : List[A]) : A = {
list match {
case (x :: Nil) => x
case (_ :: xs) => last_rec(xs)
case Nil => throw new NoSuchElementException
}
}
我想编译代码,我正在被编译器“大喊”:
PS D:\workspace\scala\P99> scalac .\P01.scala
.\P01.scala:18: error: could not optimize @tailrec annotated method last2: it contains a recursive call not in tail position
case Nil => throw new NoSuchElementException
^
one error found
如果我删除@tailrec注释 - 代码编译。如何修改代码以进行尾部优化?
答案 0 :(得分:3)
你得到了一个错字。您的方法称为last_rec
,您正在调用last
,这显然是未定义的。所以只需将其重命名为last
即可。顺便说一下,您应该返回Option[A]
而不是A
。这样,您可以在找不到任何内容时返回None
,而不是抛出丑陋的NoSuchElementException
。
答案 1 :(得分:1)
删除拼写错误并添加agilesteel的建议后:
@tailrec
def last_rec[A](list : List[A]) : Option[A] = {
list match {
case (x :: Nil) => Some(x)
case Nil => None
case (_ :: xs) => last_rec(xs)
}
}
答案 2 :(得分:1)
在这种情况下,我会做agilesteel所建议的。
但是,如果你真的想抛出异常(在另一个不同的用例中),你可以用静态类型的方式来做:
@tailrec
def last_rec[A](list : List[A]) : Either[NoSuchElementException,A] = {
list match {
case (x :: Nil) => Right(x)
case (_ :: xs) => last_rec(xs)
case Nil => Left(new NoSuchElementException)
}
}
以后你可以:
last_rec(Nil) match {
case Right(s) => println("Got a value")
case Left(e) => println("Got an exception")
}