Почему дженерики называются дженериками? - PullRequest
20 голосов
/ 21 ноября 2008

Может ли кто-нибудь объяснить мне, почему дженерики называют дженериками, рискуя стать деревенским идиотом? Я понимаю их использование и преимущества, но если определение универсального является «общим», а универсальные коллекции являются безопасными по типу, то почему это не неправильное название?

Например, ArrayList может содержать все, что является объектом:

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

в то время как универсальная коллекция типа string может содержать только строки:

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

Мне просто непонятно, почему это называется "универсальным". Если ответ «... которые позволяют разрабатывать классы и методы, которые откладывают спецификацию одного или нескольких типов до тех пор, пока класс или метод не будут объявлены и реализованы клиентским кодом». с здесь , тогда, я полагаю, это имеет смысл. Возможно, у меня возникла эта умственная ошибка, потому что я начал программировать только после того, как Java представила дженерики, поэтому я не вспоминаю время до них. Но все же ...

Любая помощь приветствуется.

Ответы [ 9 ]

20 голосов
/ 21 ноября 2008

«Дженерик» говорит о реализации. Вы пишете единственную реализацию «универсального» списка, которая работает с любым типом, вместо того, чтобы писать конкретные реализации для каждого типа, который вы хотите использовать.

13 голосов
/ 25 ноября 2009

Я думаю, что правильный ответ на подобные вопросы - это почти всегда "исторические причины, в основном". Дженерики с таким же успехом можно было бы назвать «схемами» или «классами» или «семействами типов», или «родами», или «функциями типов», или «статиками», или «греческими типами», или любыми другими миллионами вещей. Давным-давно кто-то решил использовать слово «универсальный», и оно застряло.

«Дженерик» в смысле Java относится, по крайней мере, к середине 1970-х годов. Министерство обороны США готовило документ с требованиями для своего нового языка программирования (который станет ADA). Ранний проект ( «Деревянник» , август 1975 г.) гласит:

Параметры времени компиляции необходимы в расширяемых языках, чтобы разрешить спецификацию общих процедур и структур данных, таких как стеки и очереди, без повторения определения для каждого типа элемента.

Это единственное использование «универсального» в документе. Мне не ясно, как это было задумано. Но к июлю 1977 года ( «Жестянщик» ) был целый параграф о дженериках, и термин явно стал означать нечто конкретное:

12D. ОБЩИЕ ОПРЕДЕЛЕНИЯ

Должна быть возможность определять функции, процедуры и типы с параметрами, которые создаются во время трансляции при каждом вызове. Такими параметрами могут быть любые определенные идентификаторы (в том числе для переменных, функций или типов), выражение или оператор. Эти параметры, как и все остальные параметры, должны оцениваться в контексте вызова.

К июню 1978 г. ( «Сталман» ) был создан жаргон; в других разделах документа использовались другие термины «родовой», которые явно ссылались на эту функцию. На готовом языке generic было зарезервированным словом.

Авторы этих документов перечислены на сайте, и, вероятно, большинство из них все еще существуют. Было бы здорово позвонить им и спросить, что они помнят.


Самое раннее правдоподобно связанное использование «родового», которое я нашел в научных кругах, было в книге Робина Милнера «1029 *« Теория полиморфизма типов в программировании » (1978) (и он чувствует необходимость объяснить, что он имеет в виду под« » «универсальный», так что в то время он не мог использоваться в академических кругах):

Так что это универсальный тип map , то есть любому экземпляру map в рамках этого объявления должен быть назначен некоторый экземпляр замещения этого типа.

«Переменная общего типа» стала жаргоном CS.

3 голосов
/ 25 ноября 2009
bool Equals(int x, int y)

Приведенный выше метод может сравнивать только целые числа, поэтому мы можем сказать, что он специализирован для сравнения целых чисел.

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

Приведенный выше метод может сравнивать значения любого типа, поэтому мы можем сказать, что он не специализированный для какого-либо конкретного типа - это универсальный .

1 голос
/ 21 ноября 2008

Хорошо, возьми это с крошкой соли, потому что я полностью догадываюсь, но мне интересно, может ли это быть подлостью "порождающих типов".

Концептуально, когда вы специализируете List на List , он генерирует новый тип. По крайней мере, так работает в шаблонах C ++ и в обобщениях C #.

В Java, поскольку параметризация отбрасывается компилятором с использованием стирания типа, он фактически не генерирует новый специализированный тип, так что, кто знает?

Полагаю, вы могли бы сказать, что Java реализует обобщенную версию порождающих типов:)


В режиме редактирования:

Вот еще одна точка зрения ...

Тип List - это не то, о чем они говорят, когда ссылаются на «универсальный» тип. Я думаю, что терминология на самом деле относится к типу List , то есть как тип существует в его общей форме. List является специализацией универсального List .

1 голос
/ 21 ноября 2008

Я не хочу вдаваться в семантику языка (английский, а не java) и рискую ответить вам тавтологией; универсальный метод называется generic, потому что, как вы сказали, его можно использовать в общем смысле, он не имеет определенного типа, его можно использовать обычно

0 голосов
/ 21 ноября 2008

Поскольку вы создаете «универсальный» код, который будет способен работать с любым типом (в пределах указанных ограничений) таким же образом ...

Хороший пример, с которым вы знакомы, это оператор Add, который можно использовать практически на любом языке ... он может "добавлять" целые числа, числа с плавающей запятой, двойные числа, десятичные числа, двоичные числа, шестнадцатеричные числа независимо от того, подписаны они, не засечены, сколько биты они есть, и т.д ...

0 голосов
/ 21 ноября 2008

Класс, который принимает объекты, НЕ является универсальным, он очень определенно принимает тип , который сам является универсальным типом. Универсальный класс, с другой стороны, может использоваться с любым конкретным типом.

0 голосов
/ 21 ноября 2008

Я не "носитель" английского языка, поэтому я могу ошибаться, но суть "Дженерики" в том, что типы "Определить Дженерики" не так ли?

0 голосов
/ 21 ноября 2008

Если бы они называли это «параметром (ами) типа» », люди бы спутали его с параметрами типа Тип.

Кроме того, ArrayList не является «универсальным». Он работает ТОЛЬКО с типами объектов. Если вы спросите его о чем-то, он даст вам ссылку на объект. Это очень специфическое поведение.

...