心里种花,人生才不会荒芜,如果你也想一起成长,请点个关注吧。
Kotlin 中的泛型是一种允许类型参数化的特性。它可以增强代码的重用性、类型安全性和可读性。在实际编写代码时,通过泛型,你可以编写更为通用的类和方法,而不必具体针对某种特定类型。
基本语法
在 Kotlin 中,使用尖括号 <>
来定义泛型。例如,泛型类的定义如下:
class Box<T>(t: T) {
var value = t
}
这里,T
是一个类型参数,可以在类的任何成员中使用。你可以像这样创建 Box
对象:
val intBox = Box<Int>(10)
val stringBox = Box<String>("Hello")
泛型函数
同样,你也可以定义泛型函数:
代码语言:javascript复制fun <T> singletonList(item: T): List<T> {
return listOf(item)
}
调用泛型函数:
代码语言:javascript复制val list = singletonList(1) // 返回 List<Int>
泛型约束
有时你可能希望类型参数满足某些条件,比如必须是某个类的子类或实现了某个接口。这可以通过泛型约束实现:
代码语言:javascript复制fun <T : Comparable<T>> sort(list: List<T>) {
// sort implementation
}
在这个例子中,类型参数 T
被约束为 Comparable
的子类型。
型变(Variance)
Kotlin 中的型变分为协变(Covariance)和逆变(Contravariance)。协变允许子类型替换父类型,而逆变则相反。
协变
协变使用 out
关键字修饰类型参数。这意味着类型参数只能出现在输出位置:
class Producer<out T>(private val value: T) {
fun produce(): T {
return value
}
}
val producer: Producer<Number> = Producer<Int>(10) // 合法
逆变
逆变使用 in
关键字修饰类型参数。这意味着类型参数只能出现在输入位置:
class Consumer<in T> {
fun consume(item: T) {
// Consume the item
}
}
val consumer: Consumer<Number> = Consumer<Any>() // 合法
泛型实战
以下是一个实际示例,展示如何在 Kotlin 中使用泛型构建一个通用的数据缓存系统:
代码语言:javascript复制class Cache<K, V> {
private val map = mutableMapOf<K, V>()
fun put(key: K, value: V) {
map[key] = value
}
fun get(key: K): V? {
return map[key]
}
fun remove(key: K): V? {
return map.remove(key)
}
fun clear() {
map.clear()
}
}
// 使用这个缓存类
fun main() {
val cache = Cache<String, Int>()
cache.put("key1", 1)
cache.put("key2", 2)
println(cache.get("key1")) // 输出 1
println(cache.get("key2")) // 输出 2
cache.remove("key1")
println(cache.get("key1")) // 输出 null
cache.clear()
println(cache.get("key2")) // 输出 null
}
通过这个 Cache 类,你可以缓存任意类型的键值对,比如 String
对应 Int
,或者其他任意类型的组合:
val stringCache = Cache<String, String>()
val intCache = Cache<Int, Double>()
总之,泛型是 Kotlin 中非常强大且灵活的特性,可以使你的代码更具复用性和类型安全性。通过以上的基础知识和实战示例,你可以更好地理解和应用泛型。
END
点赞转发,让精彩不停歇!关注我们,评论区见,一起期待下期的深度好文!