【问题标题】:Why are generics called generics?为什么泛型称为泛型?
【发布时间】:2010-09-23 11:29:18
【问题描述】:

冒着成为农村白痴的风险,有人可以向我解释为什么泛型被称为泛型吗?我了解它们的用法和好处,但是如果 definition of generic 是“通用的”并且通用集合是类型安全的,那么为什么这不是用词不当?

例如,一个 ArrayList 可以保存任何对象:

ArrayList myObjects = new ArrayList();
myObjects.Add("one");
myObjects.Add(1);

虽然字符串类型的泛型集合只能保存字符串:

var myStrings = new List<string>();
myStrings.Add("one");
myStrings.Add("1");

我只是不清楚为什么它被称为“通用”。如果答案是“......这使得设计类和方法成为可能,这些类和方法可以推迟一种或多种类型的规范,直到类或方法被客户端代码声明和实例化。”来自here,那么我认为这是有道理的。也许我有这种心理失误,因为我是在 Java 引入泛型之后才开始编程的,所以我不记得它们之前的时间。不过还是……

感谢任何帮助。

【问题讨论】:

    标签: generics language-agnostic semantics


    【解决方案1】:

    “通用”是指实现。您编写一个适用于任何类型的单个“通用”列表实现,而不必为要使用的每种类型编写特定的实现。

    【讨论】:

    • 好的,这是有道理的。所以实现是通用的,直到你实例化它,此时它变成一个“特定的”通用? :)
    • 或者更确切地说,您正在获取通用的特定实例:P
    • 不要这样使用实例,“实例”已经意味着什么,
    • “特定泛型”实际上通常称为“专业化”,尽管它取决于语言。例如,在 .NET 中,我们谈到“开放的泛型类型”(那些仍然有未填充类型参数的类型)和“封闭的泛型类型”(那些没有的)。
    【解决方案2】:

    我认为此类问题的正确答案几乎总是“主要是历史原因”。泛型也可以被称为“方案”或“类”或“类型族”或“类”或“类型函数”或“静态”或“希腊类型”或其他一百万种事物。很久以前有人决定使用“通用”这个词,结果卡住了。

    Java 意义上的“通用”至少可以追溯到 1970 年代中期。美国国防部正在为其新的编程语言(后来的 ADA)编写一份需求文档。一份初稿("Woodenman",1975 年 8 月)说:

    在可扩展语言中需要编译时间参数,以允许规范通用过程和数据结构(例如堆栈和队列),而无需为每种元素类型重复定义。

    这是文档中唯一使用“通用”的地方。我不清楚它是如何打算的。但是到了 1977 年 7 月 ("Tinman"),有整段关于泛型,而且这个词显然已经有了特定的含义:

    12D。通用定义

    应该可以使用在每次调用的翻译过程中实例化的参数来定义函数、过程和类型。此类参数可以是任何已定义的标识符(包括用于变量、函数或类型的标识符)、表达式或语句。与所有其他参数一样,这些参数应在调用的上下文中进行评估。

    到 1978 年 6 月 ("Steelman"),它已成为行话;在文件的其他部分中,"通用"一词还有其他用途,明确提到了这一特征。在完成的语言中,generic 是保留字。

    网站上列出了这些文档的作者,而且大概大多数人都还在。打电话问他们记得什么会很好。


    我在学术界发现的最早与“通用”相关的用法是在 Robin Milner 的"A theory of type polymorphism in programming" (1978) 中(他觉得有必要解释他所说的“通用”是什么意思,所以它不可能有共同之处当时在学术界使用):

    所以这是 map 的泛型类型,也就是说,对于在此声明范围内的任何 map 的出现,都必须分配一些该类型的替换实例。

    “泛型类型变量”变成了 CS 行话。

    【讨论】:

    • 仿制药的伟大历史。谢谢!
    【解决方案3】:
    bool Equals(int x, int y)
    

    上述方法只能比较整数,所以可以说它是专门比较整数的。

    bool Equals<T>(T x, T y);
    

    上述方法可以比较任何类型的值,因此我们可以说它不是专门针对任何特定类型的——它是通用的

    【讨论】:

    • 你会在方法体中放什么?
    【解决方案4】:

    我不想进入语言的语义(英语,而不是 java),并冒着用重言式回答你的风险;泛型方法称为泛型,因为正如您所说,它可以用于一般意义上,它没有特定的类型,可以通用

    【讨论】:

    • 这对我来说很有意义......在框架级别,List&lt;T&gt;它是通用的。它在实现中变得具体,List&lt;string&gt;
    【解决方案5】:

    好吧,对此持保留态度,因为我完全在猜测,但我想知道它是否可能是“生成类型”的混蛋。

    从概念上讲,当您将 List 特化为 List 时,它会生成一个新类型。至少,这是它在 C++ 模板和 C# 泛型中的工作方式。

    在 Java 中,由于编译器使用类型擦除来丢弃参数化,它实际上不会生成新的专用类型,所以谁知道呢?

    我想你可以说 Java 实现了生成类型的泛化版本:)


    编辑中:

    这是另一种观点...

    当他们引用“通用”类型时,类型 List 并不是他们所说的。我认为该术语实际上是指 List 类型,这就是该类型以其通用形式存在的方式。 List 是泛型 List 的特化。

    【讨论】:

      【解决方案6】:

      如果他们称其为“类型参数”,人们会将其与 Type 类型的参数混淆。

      另外,ArrayList 不是“通用的”。它仅适用于对象类型。如果你向它提出要求,它会给你一个对象引用。这是一种非常具体的行为。

      【讨论】:

      • 谢谢,我正在研究这一点,并在我的谷歌搜索中看到了这篇文章,bytes.com/forum/thread244697.html 那时我意识到 Jon Skeet 一直在任何地方。
      【解决方案7】:

      一个接受对象的类不是通用的,它非常具体地接受一个本身就是一个通用类型的type。另一方面,泛型类可以与任何特定类型一起使用。

      【讨论】:

        【解决方案8】:

        因为您正在创建能够以相同方式对任何类型(在您指定的约束范围内)进行操作的“通用”代码......

        你熟悉的一个很好的例子是 Add 运算符几乎可以用于任何语言......它可以“添加”整数、浮点数、双精度数、小数、二进制、十六进制,无论它们是否有符号、无符号、有多少他们是位,等等......

        【讨论】:

          【解决方案9】:

          我不是“以英语为母语”的人,所以我可能是错的,但“泛型”的重点是定义泛型类型,不是吗?

          【讨论】:

            猜你喜欢
            • 2013-01-11
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2012-12-28
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多