Почему List [T], а не List [Int]?Что означает Т? - PullRequest
5 голосов
/ 30 ноября 2011

Во всех примерах, которые я готов, появляется определение такого рода функций:

def firstElementInList[T](l: List[T]): T

Я привык видеть List[Int], поэтому это был бы список целых чисел.В этом случае я предполагаю, что T - любой тип (пожалуйста, исправьте меня, если я не прав).На самом деле меня настигает [T] сразу после firstElementInList

Ответы [ 3 ]

9 голосов
/ 30 ноября 2011

Это просто способ сказать: эта функция ссылается на один универсальный тип T (вы правы T - любой тип ).

Если у вас есть несколько методов внутри одного класса:

def firstElementInList[T](l: List[T]): T = l.head
def  lastElementInList[T](l: List[T]): T = l.last

тогда каждый метод имеет свой собственный тип T, поэтому вы можете вызывать первый метод со списком String s, а второй - со списком Int s.

Однако весь класс, содержащий оба этих метода, также может иметь тип:

class Foo[T] {
  def firstElementInList(l: List[T]): T = l.head
  def  lastElementInList(l: List[T]): T = l.last
}

В этом случае вы выбираете тип во время Foo создания объекта:

val foo = new Foo[String]

и компилятор не позволит вам вызывать методы экземпляра foo с любым другим типом, кроме List[String]. Также обратите внимание, что в этом случае вам больше не нужен тип [T] для метода - он взят из включающего класса.

3 голосов
/ 30 ноября 2011

T является «несвязанным» типом.Другими словами, List<T> является сокращением для «списка вещей».

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

List<Person> people = new List<Person>();

, который будет связывать T с людьми.Теперь, когда вы получите доступ к List, он будет гарантировать, что везде, где ранее существовал несвязанный T, он будет действовать так, как если бы он был написан с «People» в этой позиции.Например, public T remove(int) вернет T, который связан с «Люди» в списке людей.Это избавляет от необходимости добавлять явные приведения.Это также гарантирует, что единственными элементами в List являются как минимум People.

List<Person> people = new List<Person>();  // T is bound to "People"
List<Account> accounts = new List<Account>();   // T is bound to "Account"
Person first = people.remove(0);
Account firstAccount = accounts.remove(0);

// The following line fails because Java doesn't automatically cast (amongst classes)
Account other = people.remove(0);

// as people is a List<T> where T is bound to "People", people.remove(0) will return
// a T which is bound to People.  In short it will return something that is at least an
// instance of People.  This doesn't cast into an account (even though there are other
// lists which would).

Обратите внимание, что комментарий минимум People является индикатором того, чтосписок может содержать несколько объектов, но все объекты должны быть подклассами людей.

1 голос
/ 30 ноября 2011

То есть параметризация функции: ваше предположение было верным: если вы передадите ей List из Ints, эта функция должна вернуть Int, если вы передадите List из Strings, возвращаемое значение должно быть String и т. д. Кроме того, вы можете использовать этот тип в области функций, например, как это:

def foo[T](l: List[T]): T = {
...
val z = collections.mutable.HashMap[String,T]
...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...