java中的接口是类吗
222
2023-05-03
Kotlin 基础教程之泛型
Kotlin 支持泛型, 语法和 java 类似。
例如,泛型类:
class Hello
val box = Box
val box1 = Box(2)
泛型函数:
fun
// do something
}
val list = foo
fun
// 扩展函数
}
fun
// 多个泛型参数
}
类型变异
Java 的泛型中,最难理解的就是通配符。Java 中使用通配符是由于泛型类型是不可变的,比如 List
为了解决此问题,Java 提供了通配符类型参数(wildcard type argument)。如果你只能从一个集合取得元素, 那么就可以使用一个 String 组成的集合, 并从中读取 Object 实例,这个时候用? extends T. 反过来, 如果你只能向集合 放入 元素, 那么就可以使用一个 Object 组成的集合, 并向其中放入 String, 这个时候用? super T。
Kotlin 不存在这样的通配符,提供了两种方法:声明处类型变异(declaration-sitevariance), 以及类型投射(type projection)。
假设我们有一个泛型接口 Source
// Java
interface Source
T nextT();
}
void demo(Source
Source
// ...
}
为了解决这个问题, 我们不得不将对象类型声明为 Source extends Object> , 其实是毫无意义的, 编译器并不理解这一点。
在 Kotlin 中, 我们有办法将这种情况告诉编译器. 这种技术称为声明处的类型变异(declaration-sitevariance): 我们可以对 Source 的 类型参数 T 添加注解, 来确保 Source
abstract class Source
abstract fun nextT(): T
}
fun demo(strs: Source
val objects: Source
// ...
}
一般规则是: 当 C 类的类型参数 T 声明为 out 时, 那么在 C 的成员函数中, T 类型只允许出现在输出位置, 这样的限制带来的回报就是, 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
}
类型投射(Type projection)
class Array
fun get(index: Int): T { /* ... */ }
fun set(index: Int, value: T) { /* ... */ }
}
这个类对于类型参数 T 既不能协变, 也不能反向协变. 这就带来很大的不便。
fun copy(from: Array
assert(from.size == to.size)
for (i in from.indices)
to[i] = from[i]
}
val ints: Array
val any = Array
copy(ints, any) // 错误: 期待的参数类型是 (Array
我们需要确保的就是 copy() 函数不会做这类不安全的操作. 我们希望禁止这个函数向 from 数组
写入 数据, 我们可以这样声明:
fun copy(from: Array
// ...
}
这种声明在 Kotlin 中称为 类型投射(type projection): 我们声明的含义是, from 不是一个单纯的数组, 而是
一个被限制(投射)的数组: 我们只能对这个数组调用那些返回值为类型参数 T 的方法。
也可以使用 in 关键字来投射一个类型。
fun fill(dest: Array
// ...
}
星号投射(Star-projection)
泛型约束(Generic constraint)
对于一个给定的类型参数, 所允许使用的类型, 可以通过 泛型约束(generic constraint) 来限制。
最常见的约束是 上界(upper bound), 与 Java 中的 extends 关键字相同:
fun
// ...
}
对于类型参数 T , 只允许使用 Comparable
sort(listOf(1, 2, 3)) // 正确: Int 是 Comparable
sort(listOf(HashMap
// Comparable
泛型类型
Java 里面的泛型不支持类型, 比如 T.class这样的代码获取不到类型。Kotlin 泛型函数通过内联函数可以获取泛型的类型,比如:
inline fun
println("My type parameter is " + T::class.qualifiedName)
}
inline fun
return this.filter { it is T }.map { it as T }
}
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~