我试图使用模式匹配在scala中找到列表的最后一个元素。我尝试了以下代码
def last[A](list: List[A]):A = list match {
case head :: Nil => head
case head :: tail => last(tail)
case _ => Nil
}
最后一种情况,即案例_ => Nil因类型不匹配而抛出错误(发现Nil.type需要A)
我知道这个问题可以通过其他方法解决,但只使用模式匹配是否有办法解决这个问题?
由于列表是泛型类型,所以我不能用类型A的默认值替换Nil,它只能在运行时确定。
删除此行: case _ => Nil 显然正在发挥作用,但警告说如果Nil参数会失败。
那么,在这种情况下如何处理Nil参数呢?
答案 0 :(得分:27)
您可以使用:+
进行模式匹配。
def last[A](list: List[A]) = list match {
case init :+ last => Some(last)
case _ => None
}
答案 1 :(得分:3)
使用Option[T]
返回结果,所以如果有一些元素返回Some(lastElement)
,否则Option.empty
示例,
def last[A](list: List[A]): Option[A] = list match {
case head :: Nil => Option(head)
case head :: tail => last(tail)
case _ => Option.empty
}
it("returns last element") {
assert(last(List("apple")) == Some("apple"))
assert(last(List("apple", "mango")) == Some("mango"))
assert(last(List()) == Option.empty)
assert(last(List()) == None)
}
如何访问Option[T]
?
last(List("In absentia", "deadwind")) match {
case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}") //prints Yayy there was lastValue = deadwind
case None => println("Oops list was empty")
}
last(List()) match {
case Some(lastValue) => println(s"Yayy there was lastValue = ${lastValue}")
case None => println("Oops list was empty") //prints Oops list was empty
}
// or using map
last(List("In absentia", "deadwind")).map(lastValue => print(s"lastValue is ${lastValue}"))
答案 2 :(得分:2)
由于您不确定您的列表是否包含任何对象,因此您应该以一般方式处理此类情况。我建议您在last
方法中返回选项类型,如下所示:
def last[A](list: List[A]): Option[A] = list match {
case head :: Nil => Some(head)
case head :: tail => last(tail)
case _ => None
}
然后在您的代码中,您可以使用类似monad的界面来处理结果。您可以使用map
并使用提供的函数处理数据,也可以使用get
方法选项,以防您完全确定列表不为空。