Kotlin中支持的泛型有哪些?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
成都创新互联公司是一家以网络技术公司,为中小企业提供网站维护、网站建设、做网站、网站备案、服务器租用、申请域名、软件开发、重庆小程序开发等企业互联网相关业务,是一家有着丰富的互联网运营推广经验的科技公司,有着多年的网站建站经验,致力于帮助中小企业在互联网让打出自已的品牌和口碑,让企业在互联网上打开一个面向全国乃至全球的业务窗口:建站联系热线:028-86922220
例如,泛型类:
class Hello(val value: T) val box = Box(1) val box1 = Box(2)
泛型函数:
fun foo(item: T): List { // do something } val list = foo(1) fun T.toString2(): String { // 扩展函数 } fun put(key: K, value: V) { // 多个泛型参数 }
类型变异
Java 的泛型中,最难理解的就是通配符。Java 中使用通配符是由于泛型类型是不可变的,比如 List不是List的子类, 因而 List objs = strs 这样的代码有编译错误。为了解决此问题,Java 提供了通配符类型参数(wildcard type argument)。如果你只能从一个集合取得元素, 那么就可以使用一个 String 组成的集合, 并从中读取 Object 实例,这个时候用? extends T. 反过来, 如果你只能向集合 放入 元素, 那么就可以使用一个 Object 组成的集合, 并向其中放入 String, 这个时候用? super T。Kotlin 不存在这样的通配符,提供了两种方法:声明处类型变异(declaration-sitevariance), 以及类型投射(type projection)。假设我们有一个泛型接口 Source , 其中不存在任何接受 T 作为参数的方法, 仅有返回值为 T 的方法:// Java interface Source { T nextT(); } void demo(Source strs) { Source objects = strs; // !!! 在 Java 中禁止这样的操作 // ... }为了解决这个问题, 我们不得不将对象类型声明为 Source<? extends Object> , 其实是毫无意义的, 编译器并不理解这一点。在 Kotlin 中, 我们有办法将这种情况告诉编译器. 这种技术称为声明处的类型变异(declaration-sitevariance):我们可以对 Source 的 类型参数 T 添加注解, 来确保 Source 的成员函数只会返回T 类型, 而绝不会消费 T 类型. 为了实现这个目的, 我们可以对 T 添加 out 修饰符:abstract class Source { abstract fun nextT(): T } fun demo(strs: Source) { val objects: Source = strs // 这是 OK 的, 因为 T 是一个 out 类型参数 // ... }一般规则是: 当 C 类的类型参数 T 声明为 out 时, 那么在 C 的成员函数中, T 类型只允许出现在输出位置, 这样的限制带来的回报就是, C 可以安全地用作 C 的父类型。除了 out 之外, Kotlin 还提供了另一种类型变异注解: in. 这个注解导致类型参数反向类型变异(contravariant): 这个类型将只能被消费, 而不能被生产. 反向类型变异的一个很好的例子是 Comparable :abstract class Comparable { abstract fun compareTo(other: T): Int } fun demo(x: Comparable) { x.compareTo(1.0) // 1.0 类型为 Double, 是 Number 的子类型 // 因此, 我们可以将 x 赋值给 Comparable 类型的变量 val y: Comparable = x // OK! }类型投射(Type projection)class Array(val size: Int) { fun get(index: Int): T { /* ... */ } fun set(index: Int, value: T) { /* ... */ } }这个类对于类型参数 T 既不能协变, 也不能反向协变. 这就带来很大的不便。fun copy(from: Array, to: Array) { assert(from.size == to.size) for (i in from.indices) to[i] = from[i] } val ints: Array = arrayOf(1, 2, 3) val any = Array(3) copy(ints, any) // 错误: 期待的参数类型是 (Array, Array)我们需要确保的就是 copy() 函数不会做这类不安全的操作. 我们希望禁止这个函数向 from 数组写入 数据, 我们可以这样声明:fun copy(from: Array, to: Array) { // ... }这种声明在 Kotlin 中称为 类型投射(type projection): 我们声明的含义是, from 不是一个单纯的数组, 而是一个被限制(投射)的数组: 我们只能对这个数组调用那些返回值为类型参数 T 的方法。也可以使用 in 关键字来投射一个类型。fun fill(dest: Array, value: String) { // ... }星号投射(Star-projection)泛型约束(Generic constraint)对于一个给定的类型参数, 所允许使用的类型, 可以通过 泛型约束(generic constraint) 来限制。最常见的约束是 上界(upper bound), 与 Java 中的 extends 关键字相同:fun > sort(list: List) { // ... }对于类型参数 T , 只允许使用 Comparable 的子类型. 比如:sort(listOf(1, 2, 3)) // 正确: Int 是 Comparable 的子类型 sort(listOf(HashMap())) // 错误: HashMap 不是 // Comparable> 的子类型泛型类型Java 里面的泛型不支持类型, 比如 T.class这样的代码获取不到类型。Kotlin 泛型函数通过内联函数可以获取泛型的类型,比如:inline fun runtimeType(): Unit { println("My type parameter is " + T::class.qualifiedName) } inline fun List.collect(): List { return this.filter { it is T }.map { it as T } }看完上述内容,你们掌握Kotlin中支持的泛型有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读! 当前名称:Kotlin中支持的泛型有哪些 文章地址:http://scjiangan.com/article/iehoes.html 其他资讯 php表单更新数据库 php更新数据库字段 在python中加入函数 python中加法函数 oracle表空间怎么建 oracle创建数据表空间 oracle备份如何导出 oracle导入备份数据 windows阴间系统的简单介绍 在线咨询 拨打电话
为了解决此问题,Java 提供了通配符类型参数(wildcard type argument)。如果你只能从一个集合取得元素, 那么就可以使用一个 String 组成的集合, 并从中读取 Object 实例,这个时候用? extends T. 反过来, 如果你只能向集合 放入 元素, 那么就可以使用一个 Object 组成的集合, 并向其中放入 String, 这个时候用? super T。
Kotlin 不存在这样的通配符,提供了两种方法:声明处类型变异(declaration-sitevariance), 以及类型投射(type projection)。
假设我们有一个泛型接口 Source , 其中不存在任何接受 T 作为参数的方法, 仅有返回值为 T 的方法:
// Java interface Source { T nextT(); } void demo(Source strs) { Source objects = strs; // !!! 在 Java 中禁止这样的操作 // ... }为了解决这个问题, 我们不得不将对象类型声明为 Source<? extends Object> , 其实是毫无意义的, 编译器并不理解这一点。在 Kotlin 中, 我们有办法将这种情况告诉编译器. 这种技术称为声明处的类型变异(declaration-sitevariance):我们可以对 Source 的 类型参数 T 添加注解, 来确保 Source 的成员函数只会返回T 类型, 而绝不会消费 T 类型. 为了实现这个目的, 我们可以对 T 添加 out 修饰符:abstract class Source { abstract fun nextT(): T } fun demo(strs: Source) { val objects: Source = strs // 这是 OK 的, 因为 T 是一个 out 类型参数 // ... }一般规则是: 当 C 类的类型参数 T 声明为 out 时, 那么在 C 的成员函数中, T 类型只允许出现在输出位置, 这样的限制带来的回报就是, C 可以安全地用作 C 的父类型。除了 out 之外, Kotlin 还提供了另一种类型变异注解: in. 这个注解导致类型参数反向类型变异(contravariant): 这个类型将只能被消费, 而不能被生产. 反向类型变异的一个很好的例子是 Comparable :abstract class Comparable { abstract fun compareTo(other: T): Int } fun demo(x: Comparable) { x.compareTo(1.0) // 1.0 类型为 Double, 是 Number 的子类型 // 因此, 我们可以将 x 赋值给 Comparable 类型的变量 val y: Comparable = x // OK! }类型投射(Type projection)class Array(val size: Int) { fun get(index: Int): T { /* ... */ } fun set(index: Int, value: T) { /* ... */ } }这个类对于类型参数 T 既不能协变, 也不能反向协变. 这就带来很大的不便。fun copy(from: Array, to: Array) { assert(from.size == to.size) for (i in from.indices) to[i] = from[i] } val ints: Array = arrayOf(1, 2, 3) val any = Array(3) copy(ints, any) // 错误: 期待的参数类型是 (Array, Array)我们需要确保的就是 copy() 函数不会做这类不安全的操作. 我们希望禁止这个函数向 from 数组写入 数据, 我们可以这样声明:fun copy(from: Array, to: Array) { // ... }这种声明在 Kotlin 中称为 类型投射(type projection): 我们声明的含义是, from 不是一个单纯的数组, 而是一个被限制(投射)的数组: 我们只能对这个数组调用那些返回值为类型参数 T 的方法。也可以使用 in 关键字来投射一个类型。fun fill(dest: Array, value: String) { // ... }星号投射(Star-projection)泛型约束(Generic constraint)对于一个给定的类型参数, 所允许使用的类型, 可以通过 泛型约束(generic constraint) 来限制。最常见的约束是 上界(upper bound), 与 Java 中的 extends 关键字相同:fun > sort(list: List) { // ... }对于类型参数 T , 只允许使用 Comparable 的子类型. 比如:sort(listOf(1, 2, 3)) // 正确: Int 是 Comparable 的子类型 sort(listOf(HashMap())) // 错误: HashMap 不是 // Comparable> 的子类型泛型类型Java 里面的泛型不支持类型, 比如 T.class这样的代码获取不到类型。Kotlin 泛型函数通过内联函数可以获取泛型的类型,比如:inline fun runtimeType(): Unit { println("My type parameter is " + T::class.qualifiedName) } inline fun List.collect(): List { return this.filter { it is T }.map { it as T } }看完上述内容,你们掌握Kotlin中支持的泛型有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读! 当前名称:Kotlin中支持的泛型有哪些 文章地址:http://scjiangan.com/article/iehoes.html 其他资讯 php表单更新数据库 php更新数据库字段 在python中加入函数 python中加法函数 oracle表空间怎么建 oracle创建数据表空间 oracle备份如何导出 oracle导入备份数据 windows阴间系统的简单介绍 在线咨询 拨打电话
为了解决这个问题, 我们不得不将对象类型声明为 Source<? extends Object> , 其实是毫无意义的, 编译器并不理解这一点。
在 Kotlin 中, 我们有办法将这种情况告诉编译器. 这种技术称为声明处的类型变异(declaration-sitevariance):我们可以对 Source 的 类型参数 T 添加注解, 来确保 Source 的成员函数只会返回T 类型, 而绝不会消费 T 类型. 为了实现这个目的, 我们可以对 T 添加 out 修饰符:
abstract class Source { abstract fun nextT(): T } fun demo(strs: Source) { val objects: Source = strs // 这是 OK 的, 因为 T 是一个 out 类型参数 // ... }
一般规则是: 当 C 类的类型参数 T 声明为 out 时, 那么在 C 的成员函数中, T 类型只允许出现在输出位置, 这样的限制带来的回报就是, C 可以安全地用作 C 的父类型。
除了 out 之外, Kotlin 还提供了另一种类型变异注解: in. 这个注解导致类型参数反向类型变异(contravariant): 这个类型将只能被消费, 而不能被生产. 反向类型变异的一个很好的例子是 Comparable :
abstract class Comparable { abstract fun compareTo(other: T): Int } fun demo(x: Comparable) { x.compareTo(1.0) // 1.0 类型为 Double, 是 Number 的子类型 // 因此, 我们可以将 x 赋值给 Comparable 类型的变量 val y: Comparable = x // OK! }
类型投射(Type projection)
class Array(val size: Int) { fun get(index: Int): T { /* ... */ } fun set(index: Int, value: T) { /* ... */ } }
这个类对于类型参数 T 既不能协变, 也不能反向协变. 这就带来很大的不便。
fun copy(from: Array, to: Array) { assert(from.size == to.size) for (i in from.indices) to[i] = from[i] } val ints: Array = arrayOf(1, 2, 3) val any = Array(3) copy(ints, any) // 错误: 期待的参数类型是 (Array, Array)
我们需要确保的就是 copy() 函数不会做这类不安全的操作. 我们希望禁止这个函数向 from 数组写入 数据, 我们可以这样声明:
fun copy(from: Array, to: Array) { // ... }
这种声明在 Kotlin 中称为 类型投射(type projection): 我们声明的含义是, from 不是一个单纯的数组, 而是一个被限制(投射)的数组: 我们只能对这个数组调用那些返回值为类型参数 T 的方法。
也可以使用 in 关键字来投射一个类型。
fun fill(dest: Array, value: String) { // ... }
对于一个给定的类型参数, 所允许使用的类型, 可以通过 泛型约束(generic constraint) 来限制。
最常见的约束是 上界(upper bound), 与 Java 中的 extends 关键字相同:
fun > sort(list: List) { // ... }
对于类型参数 T , 只允许使用 Comparable 的子类型. 比如:
sort(listOf(1, 2, 3)) // 正确: Int 是 Comparable 的子类型 sort(listOf(HashMap())) // 错误: HashMap 不是 // Comparable> 的子类型
泛型类型
Java 里面的泛型不支持类型, 比如 T.class这样的代码获取不到类型。Kotlin 泛型函数通过内联函数可以获取泛型的类型,比如:
inline fun runtimeType(): Unit { println("My type parameter is " + T::class.qualifiedName) } inline fun List.collect(): List { return this.filter { it is T }.map { it as T } }
看完上述内容,你们掌握Kotlin中支持的泛型有哪些的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注创新互联行业资讯频道,感谢各位的阅读!
在线咨询
拨打电话