Kotlin基础知识九: Generics
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kotlin基础知识九: Generics相关的知识,希望对你有一定的参考价值。
参考技术A 声明一个或多个形参(type parameters),例如class Map拥有K和V两个类型参数:class Map<K, V>。当一个实例被创建时,会使用特定的实参类型(type arguments)替换形参(type parameters)。一般来说,实参类型可以由kotlin编译器推断而出,例如:
可以省去显式的类型声明(explicit type specification)。如果创建的是一个空的list,就无法推断出实参类型,因此需要显式的指定它:
与Java不同的是,Kotlin不支持原生类型(raw types),一个原生类型就是一个没有任何类型参数的泛型类,因此定义一个generic type时必须要指定形参类型(type arguments)。
fun关键字后面紧跟<T>表示声明类型为T的形参(Type parameter)。例如:
定义一个Kotlin的泛型类List<T>如下:
其中尖括号括起来的T表示定义了一个形参类型(type parameter)T,然后T可以在class或interface中当成一个常规类型使用。
一个class可以把自身当做实参(type argument)。
例如:
String类实现了泛型的Comparable接口,并为形参类型T提供了String类型。
其中,T为Type parameter,T后面紧跟的分号加上Number表示upper bound。
对应的Java语法为:
看另外一个例子:
形参T的upper bound是一个泛型类型Comparable<T>。
当定义一个泛型类或函数时,实参类型可以是任何类型(包括Nullable)。没有指定约束的形参类型默认上界是Any?。
如果想指定一个non-null的类型约束,可以使用Any作为上界。
这时,Processor<String?>()会编译失败:
编译器在运行期(runtime)不会保留一个泛型类实例的实参类型(type arguments)。
与Java相同,Kotlin的Generics在运行时的类型是会被擦除的。也即一个Generic类的实例在运行期不会携带创建该实例时的实参类型(type arguments)。因此,对泛型类型实例使用is检验会导致编译失败(编译器已经已知的类型除外)。举例:
对generic function也是同理,在function body中无法确定被调用的实参类型(type argument)。举例:
如果把isA函数声明为inline、同时把形参声明为reified,那么这时候可以在运行期获悉被调用的是参类型。
另外一个例子是系统的filterIsInstance函数:
filterIsInstance函数的简单实现如下:
其中,reified关键字声明了实参类型(type argument)在运行期不会被擦除。
Kotlin基础-泛型
/*
* 泛型Generics
* 让一个类型能被“广泛”使用,即通用化,称之为“泛型”
* 一般用于函数的参数类型定义,让函数更通用
*
* */
fun main(args: Array<String>) {
println(2)
println("泛型")
//自定义一个泛型函数:<T>代表一个占位符,用尖括号包含
fun <T>show(para:T){
print(para)
}
show(3)
show("我也是泛型函数")
//泛型约束:<泛型占位符:类型>
fun <T:Number>sum(vararg numbers:T ):Double{
return numbers.sumByDouble { it.toDouble() }
}
print(sum(1,3,-6,9.9))
//多重约束:where,各个约束用逗号分隔,写在函数体之前
//例子:把大于某个源的部分取出并升序排列
//(99,1,2,-21,-5,9)----》2,9,99
fun <T> bigpart(list: Array<T>, threhold: T): List<T>
where T : Number,T:Comparable<T>
{
return list.filter{ it >=threhold}.sorted()
}
val b= arrayOf(1,0,55,99,3,-5,66)
print(bigpart(b,3))
}
以上是关于Kotlin基础知识九: Generics的主要内容,如果未能解决你的问题,请参考以下文章
Kotlin 协程协程底层实现 ① ( Kotlin 协程分层架构 | 基础设施层 | 业务框架层 | 使用 Kotlin 协程基础设施层标准库 Api 实现协程 )