在所有示例中,我准备好了这种函数定义不断弹出:
def firstElementInList[T](l: List[T]): T
我习惯看到List[Int]
所以它将是一个整数列表。在这种情况下,我假设T
是任何类型(如果我错了,请纠正我)。我真正感受到的是[T]
firstElementInList
答案 0 :(得分:8)
IT只是一种说法:此函数引用一个通用类型T
(您是对的T
任何类型)。
如果一个类中有多个方法:
def firstElementInList[T](l: List[T]): T = l.head
def lastElementInList[T](l: List[T]): T = l.last
然后每个方法都有自己的T
类型,因此您可以使用String
列表调用第一个方法,使用Int
列表调用第二个方法。
然而,包含这两种方法的整个类也可以有类型:
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]
作为方法 - 它取自封闭类。
答案 1 :(得分:2)
T是“未绑定”类型。换句话说,List<T>
是“事物清单”的简写。
这意味着您可以使用相同的代码将“人员列表”设为“日期列表”或“帐户列表”,您只需提供构造函数
List<Person> people = new List<Person>();
将T
绑定到人员。现在,当您访问List
时,它将保证在以前未绑定的T
存在的任何地方,它将表现为在该位置使用“人员”编写。例如,public T remove(int)
将返回绑定到人员列表中“人员”的T
。这避免了添加显式强制转换的需要。它还保证List
中的唯一项目至少人。
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注释表示列表可能包含多个对象,但所有对象必须是People的子类。
答案 2 :(得分:1)
这是函数的参数化:你的猜测是正确的:如果你将List
的{{1}}传递给它,那么该函数应该返回Ints
,如果你通过Int
的{{1}},返回值应为List
,依此类推。
此外,您可以在函数范围中使用此类型,例如像这样:
Strings