一、泛型函数
如下是泛型函数的一种构造
在fun函数标记的右边增加该函数要使用的类型形参
fun <T> List<T>.slice(indices: IntArray): List<T> { val ret = mutableListOf<T>() for (v in indices) { ret.add(this[v]) } return ret } listOf(3,4,5,6,7,8,1,2).slice(intArrayOf(4,5,3,2))
如上在调用slice之后,返回了一个新的List并且对应的类型为T
上述的调用也可以为:listOf<Int>(3,4,5,6,7,8,1,2).slice<Int>(intArrayOf(4,5,3,2))
这里listOf<Int>对应的List<T>, slice<Int>对应的fun <T> ;
但是为何实际不需要添加<Int>呢?是因为kotlin能够进行推理得到对应的类型!
二、泛型的扩展属性
这里强调扩展属性,是因为普通属性不能拥有类型参数,不能在一个类的属性中存储多个不同类型的值。例如:val <T> x: T = TODO()
如下是泛型的扩展属性的一个例子,返回列表的倒数第二个参数
val <T> List<T>.penultimate: T get() = this[size - 2] listOf(1,2,3,4).penultimate
三、泛型类
语法是:在类名称后加上一对尖括号,并把类型参数放在尖括号内来声明泛型类和接口。
interface Compareable<T> { // 这里声明一个接口,并且在该接口中声明了类型参数 fun compareTo(other: T): Int } class String1(val value: String): Compareable<String1> { // 在实现的时候需要指明接口具体要具现的类型,这里可以使用类本身作为具现类 override fun compareTo(other: String1): Int { return this.value.length - other.value.length } } val string1 = String1("kk") println(string1.compareTo(String1("qqq")))
四、类型参数的约束
类型参数的约束可以限制泛型类和函数的类型实参的类型
指定泛型类型形参的上界即泛型类型必须为上界类型的子类型
如下是对应的例子
fun <T: Number> List<T>.sum(): Int { // 这里指定了上界是Number var ret = 0 this.forEach { ret += it.toInt() } // 因为T 是Number或者Number的子类,所以这里可以调用toInt() return ret } listOf(1,2,3).sum()
2、带类型参数约束的函数
fun <T: Comparable<T>> max(first: T, second: T): T { // T 必须是一个可比较的类型 return if (first > second) first else second } max("kk", "qqq")
3、如果要对T指定多个约束的话,则需要使用where关键字,多个约束的中间用逗号隔开,并且写在函数的最后面
fun <T> ensuretrail(seq: T): T where T: CharSequence, T: Appendable { // 这里返回的类型为T
if (!seq.endsWith('.')) {
seq.append('.')
}
return seq
}
4、当没有类型参数的约束时候,它的默认约束是Any? , 此时T是可空的类型,如果要让T非空则需要明确指定非空的类型
标签:return,kotlin,基础,ret,fun,类型,泛型,List From: https://www.cnblogs.com/czwlinux/p/17835239.html