我喜欢Differences in Generics的讨论,并且想知道是否有任何语言使用此功能特别好。
我真的不喜欢Java List<? extends Foo>
的{{1}} Liskov可替代List
的东西。为什么Foo
不能涵盖那个?
老实说,List<Foo>
?
我也记不起为什么你永远不应该返回一系列泛型:
Comparable<? super Bar>
我从不喜欢C ++中的模板,但这主要是因为没有一个编译器会为它们吐出一个远程有意义的错误消息。有一次我实际上做了public T[] getAll<T>() { ... }
17次以获得编译的东西;我从未弄清楚为什么第17次是魅力。
那么,谁真的喜欢在他们的宠物语言中使用泛型?
答案 0 :(得分:14)
Haskell很好地实现了类型构造函数参数化(泛型或参数多态)。 Scala也是如此(虽然有时需要一些手持)。
这两种语言都有更高级的类型(a.k.a.抽象类型构造函数,或类型构造函数多态,或更高阶多态)。
答案 1 :(得分:7)
哎呀,英语甚至没有很好地实现泛型。 :)
我的偏见是C#。主要是因为这是我目前正在使用的,我已经用它们取得了良好的效果。
答案 2 :(得分:7)
我认为Java中的泛型实际上非常好。 List<Foo>
与List<? extends Foo>
不同的原因是当Foo
是Bar
的子类型时,List<Foo>
不是List<Bar>
的子类型。如果您可以将List<Foo>
对象视为List<Bar>
,则可以向其添加Bar
个对象,这可能会破坏事物。任何合理的类型系统都需要这个。 Java允许您将Foo[]
视为Bar[]
的子类型,但这会强制运行时检查,从而降低性能。返回此类数组时,编译器很难知道是否要进行运行时检查。
我从来不需要使用下限(List<? super Foo>
),但我认为它们可能对返回泛型值很有用。见covariance and contravariance。
总的来说,我绝对同意有关过于冗长的语法和令人困惑的错误消息的抱怨。像OCaml和Haskell这样的类型推断语言可能会让你更容易,尽管他们的错误信息也会让人感到困惑。
答案 3 :(得分:3)
我将OCaml添加到列表中,该列表具有非常泛型泛型。我同意Haskell的类型类确实做得很好,但它有点不同,因为Haskell没有OO语义,但OCaml确实支持OO。
答案 4 :(得分:1)
我使用.Net(VB.Net),并且使用泛型没有任何问题。这主要是无痛的。
Dim Cars as List(Of Car)
Dim Car as Car
For Each Car in Cars
...
Next
使用泛型集合时从来没有遇到任何问题,尽管我还没有设计出任何使用泛型的对象。
答案 5 :(得分:0)
我认为C#和VB.NET在泛型方面做得很好。