Scala:了解参数多态性 [英] Scala: understanding parametric polymorphism
问题描述
两者之间有什么区别
def drop1[A](l: List[A]) = l.tail
和
def drop1(l: List[Int]) = l.tail
提供的用法类似于
drop1(List(1,2,3))
?
何时应使用一个或另一个?为什么?尽管我可以理解第二个示例,但我并不真正理解第一个示例的目的.
When should one or the other be used and why? Whereas I can understand the second example, I don't really understand the purpose of the first one.
推荐答案
真的很简单.您的第一个示例涉及泛型的概念.
It's very simple really. Your first example refers to the concept of generics.
泛型有一个简单的目标,就是使某些方法成为泛型,例如非类型依赖.
Generics have a simple goal, to make certain methods generic, e.g non-type dependant.
让我们看一下这个简单的例子.假设我要为List
编写drop1
方法.
Lets look at this trivial example. Say I want to write a drop1
method for List
.
我可以为每种类型写一个:(慢,重复):
I can either write one for every single type:(slow, repetitive):
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
您将看到如何为每种类型编写以上代码.为了克服这个问题,您可以使用泛型:
You can see how you'd have to write the above for every single type. To overcome this, you have generics:
def drop1[A](l: List[A]): List[A] = l.tail // this works for any given type.
本质上是这样说的:无论List中包含什么类型,请给我尾巴.
无需为几乎无限数量的类型编写成千上万的drop1
变体,我只需要编写一个.
Which essentially says: Whatever the type contained in the List is, give me the tail.
Instead of writing thousands of variants of drop1
for the virtually infinite number of types, I only need to write one.
现在在Scala中,最好使用以下方法来实现:
Now in Scala, your implementation is best done with:
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
方法.
It is also generally a bad idea to rename well known library methods. A tail
operation is unsafe and a drop
is safe. All you are causing is confusion, since there is a default drop
method.
List(1, 2, 3) drop 1
这篇关于Scala:了解参数多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!