Kotlin笔记之泛型(一)

mac2024-04-18  31

文章目录

类型参数区别 泛型类和函数泛型类泛型函数 类型参数约束类型参数非空、可空

类型参数

泛型允许定义带类型形参的类型,当这种类型的实例被创建出来的时候,类型形参被替换成称为类型实参的具体类型

实例

// 源码listOf函数声明 fun <T> listOf(vararg elements: T): List<T> val list=listOf("hello","world") // 编译器推导 val list= listOf<String>()// 显示说明

上例中 T 为类型形参 ,并且函数的返回类型使用了类型形参

区别

Kotlin 要求类型实参要么被显示地说明,要么能被编译器推导推导出来Kotlin 不支持原生态类型,类型实参必须定义Java 允许使用没有类型参数的泛型类型(原生态类型),因为支持老版本代码兼容

泛型类和函数

泛型类

Kotlin 通过在类名称后加上一对尖对号,并把类型参数放在尖对号内来声明泛型类及泛型接口。一旦声明之后,就可以在类的主体内像其他类型一样使用类型参数。

// 泛型类 class Gen<T>(private var t: T) { fun getValue() :T{ return t } } // 泛型接口 interface List<T>{ public operator fun get(index: Int): T }

小结: 如果类继承了泛型类(实现了泛型接口),就得为基础类型的泛型形参提供了一个类型实参,它可以是具体类型或者另一个类型形参:

class GenList:List<String>{ override fun get(index :Int):String=... } class ArrayList<T>:List<T>{ override fun get(index :Int):T=... }

泛型函数

泛型函数有它自己的类型形参,这些类型形参在每次函数调用时都必须替换成具体的类型实参

fun <T> printMessage(msg :T){ when (content) { is Int ->{"该信息数据类型是整型"} else ->{"该信息数据类型不是整型"} } }

注意: 普通(即非拓展)属性不能拥有类型参数,不能在一个类的属性中存储多个不同类型的值,因此声明泛型非拓展函数没有任何意义

类型参数约束

类型参数约束可以限制作为泛型类和泛型函数的类型实参的类型;如果把一个类型指定为泛型类型形参的上界约束,在泛型类型具体的初始化中,其对应的类型实参就必须是这个具体类型或者它的子类型

示例

// 函数声明 fun <T:Number> List<T>.sum() :T // 具体类型实参继承了Number,函数调用是允许的 println(listOf(1,2,3).sum())

上例中,通过在类型参数后指定上界来定义约束,把冒号放在类型参数名称之后,作为类型形参上界的类型紧随其后;一旦指定了类型形参T的上界,就可以把类型T的值当作它的上界(类型)的值使用

类型参数非空、可空

如果声明的是泛型类或者泛型函数,任何类型实参,包括那些可空的类型实参,都可以替换它的类型形参;没有指定上界的类型形参将会使用Any?这个默认上界

// 类型参数可空 默认上界的类型形参是Any? class Person<T>{ fun name(value :T){ value?.hashcode() } } // 类型参数非空 默认上界的类型形参是Any class Person<T:Any>{ fun name(value :T){ value?.hashcode() } }

注意:可以通过指定任意非空类型作为上界,来让类型参数非空,不光是类型Any

最新回复(0)