22

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

例如,一个 ArrayList 可以包含任何对象:

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

而字符串类型的通用集合只能保存字符串:

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

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

任何帮助表示赞赏。

4

9 回答 9

21

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

于 2008-11-21T16:01:27.697 回答
15

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

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

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

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

12D。通用定义

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

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

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


我在学术界发现的最早与“泛型”相关的用法是在 Robin Milner 的“编程中的类型多态性理论”(1978 年)中(他觉得有必要解释他所说的“泛型”是什么意思,所以它不能有当时在学术界普遍使用):

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

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

于 2009-11-24T23:15:31.110 回答
4
bool Equals(int x, int y)

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

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

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

于 2009-11-24T23:26:43.043 回答
1

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

于 2008-11-21T16:01:27.180 回答
1

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

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

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

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


编辑:

这是另一种观点...

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

于 2008-11-21T16:04:39.390 回答
0

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

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

于 2008-11-21T16:00:49.150 回答
0

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

于 2008-11-21T16:02:07.587 回答
0

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

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

于 2008-11-21T16:02:07.803 回答
-1

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

于 2008-11-21T16:01:05.497 回答