Полнотекстовый поиск показывает, что «переменная типа» впервые появляется в разделе 2:
Пока тип элемента известен на сайте вызова, это может быть выражено с помощью простых обобщений с использованием apolymorphi c метод с фиктивной переменной типа:
〈X〉void m1(List〈X〉list) { ... }
Как вы можете видеть, в этом примере вообще не используются символы подстановки, что противоречит вашему предположению, что переменная типа используется для ссылки на символы подстановки в частности ".
Итак, что является переменными типа? Поскольку термин не определен в самом документе, он должен быть определен в одной из его ссылок.
Но какой? Так как ссылки обычно используются перед первым использованием терминов, ссылка должна быть в разделе введения, и из контекста это предложение выглядит наиболее многообещающим:
Параметри c полиморфизм - также известен как дженерик или дженерики - зародились в мире нефункционального программирования [21]
Таким образом, мы, вероятно, найдем ответ в
[21] Робин Милнер. Теория полиморфизма типов в программировании. Journal of Computer and System Sciences, 17: 348–375, август 1978 года.
В поисках названия этой статьи найден PDF-файл с полным текстом, и действительно, эта статья classi c содержит множество примеры для переменных типа, таких как:
ПРИМЕР 1.
Отображение функции в списке.
let rec map(f, m) = if null (m) then nil
else cons (f(hd(m)), map (f, d(m)))
Интуитивно понятная функция, объявленная таким образом map
, берет функцию из вещей одного рода в вещи другого рода и список вещей первого рода и создает список вещей второй род. Поэтому мы говорим, что карта имеет тип
((α → β) x α список) → β список
, где α, β - переменные типа.
Итак переменная типа - это просто переменная (в математическом смысле), которая будет содержать тип. Переменная типа может быть введена параметром типа, но, как показывает Милнер, переменные типа также могут быть введены другими способами. (Обратите внимание, что α и β не отображаются в определении map
?)
Нечто подобное происходит, когда компилятор Java выполняет захват с подстановочными знаками. Например, если мы напишем:
List<?> sourceList = ...;
List<?> targetList = ...;
targetList.add(sourceList.get(0));
, компилятор скажет:
The method add(capture#1-of ?) in the type List<capture#1-of ?> is not applicable for the arguments (capture#2-of ?)
Как мы можем видеть, рассуждая о типах подстановочных знаков, компилятор "захватывает" значение подстановочных знаков в переменные типа fre sh типа capture#1-of ?
. В отличие от переменных типа, вводимых параметрами типа, эти переменные типа никогда не отображаются в исходном коде.
И именно поэтому при обсуждении захвата с подстановочными знаками в документе Wild FJ говорится о переменных типа, не представленных параметрами типа.