之间有什么区别

def drop1[A](l: List[A]) = l.tail




def drop1(l: List[Int]) = l.tail


只要用法看起来像

drop1(List(1,2,3))




什么时候应该使用另一个?为什么?尽管我可以理解第二个示例,但我并没有真正理解第一个示例的目的。

最佳答案

真的很简单。您的第一个示例涉及泛型的概念。

泛型的简单目标是使某些方法成为泛型,例如非类型相关。

让我们看一下这个简单的例子。说我想为drop1写一个List方法。

我可以为每种类型写一个:(慢,重复):

def drop1(l: List[Int]): List[Int] = l.tail // this only works for Int

def drop1(l: List[String]): List[String] = l.tail // this only works for String


您可以看到如何为每种类型编写以上代码。为了克服这个问题,您可以使用泛型:

def drop1[A](l: List[A]): List[A] = l.tail // this works for any given type.


本质上说:无论列表中包含什么类型,请给我尾巴。
无需为几乎无限数量的类型编写成千上万的drop1变体,我只需要编写一个。

现在在Scala中,最好使用以下方法来实现:

implicit class ListOps[A](val l: List[A]) extends AnyVal {
   def drop1: List[A] = l match {
     case head :: tail => tail
     case Nil => Nil
   }
}
// you can now have
List(1, 2, 3).drop1


重命名众所周知的库方法通常也是一个坏主意。 tail操作不安全,而drop是安全的。由于没有默认的drop方法,您所引起的只是混乱。

List(1, 2, 3) drop 1

10-04 11:05