我正在尝试在scala中做一些示例程序以更熟悉该语言,因为我正在尝试重新实现Haskell中的一些内置方法,我确信这些方法中的大多数也是在Scala也是,但这些只是为了我的练习。我想我可以发布一些代码片段(不是所有代码片段)来获得更好的处理方式并验证我对scala的理解。如果这不是做这些事情的地方,请告诉我。
这是我的scala实现,用于获取任何列表的最后一个元素。这是正确的做事方式吗?通过使用Any
我是否丢失了列表中包含的对象的类型?这是scala中实现这种事情的方式吗?
def getLast(xs: List[Any]): Any = xs match {
case List() => null
case x :: List() => x
case _ :: ys => getLast(ys)
}
答案 0 :(得分:6)
参数化你的函数类型并使用“Nil”代替List(),如下所示:
def getLast[T](xs: List[T]): T = xs match {
case Nil => null.asInstanceOf[T]
case x :: Nil => x
case _ :: ys => getLast(ys)
}
另外,请考虑让它返回选项类型:
def getLast[T](xs: List[T]): Option[T] = xs match {
case Nil => None
case x :: Nil => Some(x)
case _ :: ys => getLast(ys)
}
用法:
val listOfInts = List(1,2,3)
assert(getLast(listOfInts).isInstanceOf[Int])
val listOfStrings = List("one","two","three")
assert(getLast(listOfStrings).isInstanceOf[String])
答案 1 :(得分:5)
首先,请避开null
,尤其是null.asInstanceOf[T]
。用原语观察危险:
scala> null.asInstanceOf[Int]
res19: Int = 0
scala> null.asInstanceOf[Boolean]
res20: Boolean = false
因此签名应该是List[T] => T
,因此空迭代器上的last
会引发异常:
def last[T](ts: List[T]): T = ts match {
case Nil => throw new NoSuchElementException
case t :: Nil => t
case t :: ts => last(ts)
}
或者改为:List[T] => Option[T]
def lastOption[T](ts: List[T]): Option[T] = ts match {
case Nil => None
case t :: Nil => Some(t)
case t :: ts => lastOption(ts)
}
def lastOption1[T](ts: List[T]): Option[T] = ts.reverse.headOption
def lastOptionInScala28[T](ts: List[T]): Option[T] = ts.lastOption // :)