发布于 2019-02-25 23:37:10
它用于指示使用泛型,而不是引用某种类型的T
。
看看这个完全有效的例子。
fun <String> MutableList<String>.swap(index1: Int, index2: Int)
现在,这可以在任何MutableList<*>
上调用,而不仅仅是MutableList<String>
。如果您不想在<String>
关键字后面写fun
,kotlin怎么知道实际上您引用的是泛型而不是kotlin.String
你展示的例子也是如此。在<>
刚刚引入一个新的泛型参数之后,kotlin会抱怨它不知道T
的类型
发布于 2019-02-26 02:27:43
(这是另一种方法。)
考虑一个正常的、非泛型函数:
fun myFun(a: Int, b: String) {
// …use a and b…
}
a
和b
是什么?它们还没有任何意义。它们只是简单地说‘当你调用这个函数时,你必须传递这些值’。你会期望函数的主体以某种方式引用它们;那就是它们被使用的时候。
现在考虑一个泛型函数:
fun <T, U> myFun(/* …use T and U… */) {
// …
}
与T
和U
. 一样--这些参数也是类型参数。与值参数一样,声明类型参数本身并不意味着什么,而是为调用函数时必须传递(显式或推断)的类型提供占位符。( <…>
声明还为指定任何约束或方差(例如<T : Number>
或<out T>
)提供了一个位置。)并且通常在以后使用这些类型参数--在这种情况下,在函数签名的其余部分。
发布于 2019-02-26 00:47:18
要添加到Lino的答案中,假设这个定义在type参数声明之后有不可见的大括号:
fun <T> \*{*\ MutableList<T>.swap(index1: Int, index2: Int) {...} \*}*\
所以这是正确的词汇作用域。如果<T>
使用函数名,您将失去此属性,使解析器复杂化,只会降低代码对人类的可读性。
还很难记住将<T>
放在扩展函数的名称之前,而放在成员函数的名称之后。够糟糕的了,它必须在课堂上完成!
Scala确实将[T]
放在方法名称之后,但这是因为它对于与扩展方法相对应的特性具有非常不同的语法。Scala 3将采用复杂的解析器方法,可能是因为类似Kotlin的语法不适合任何其他语法。
https://stackoverflow.com/questions/54880432
复制