📅  最后修改于: 2023-12-03 15:32:31.543000             🧑  作者: Mango
在面向对象编程中,泛型是指编写能够适用于多种数据类型的代码,使得代码更加通用且可读性更强。Kotlin具有一套独特的泛型系统,可以帮助程序员编写更加安全和可重用的代码。
在Kotlin中,泛型使用尖括号<T>
表示,其中T
可以是任何标识符。
定义一个泛型类:
class Example<T>(item: T) {
var data = item
}
定义一个泛型函数:
fun <T> doSomething(item: T) {
// some code
}
使用泛型:
val example = Example("Hello, World!")
val item = example.data // inferred type is String
doSomething("Hello, World!") // inferred type is String
Kotlin中类型投影分为三种:
协变是指如果A
是B
的子类型,则List<A>
是List<B>
的子类型,可以使用out
关键字使得类型成为协变:
interface Producer<out T> {
fun produce(): T
}
fun demo(strProducer: Producer<String>) {
val anyProducer: Producer<Any> = strProducer
}
逆变是指如果A
是B
的子类型,则List<B>
是List<A>
的子类型,可以使用in
关键字使得类型成为逆变:
interface Consumer<in T> {
fun consume(item: T)
}
fun demo(anyConsumer: Consumer<Any>) {
val strConsumer: Consumer<String> = anyConsumer
}
不变是指如果A
不是B
的子类型,那么List<A>
与List<B>
是没有任何关系的。
Kotlin中的is
关键字可以用来检查一个对象的类型,如果对象的类型是指定类型的子类型,那么返回true
,否则返回false
。as?
操作符可以用来将对象转换为指定类型,如果对象不是指定类型的子类型,那么返回null
。
val obj: Any = "Hello, World!"
if (obj is String) {
val str: String = obj // no need to cast
println(str)
}
val obj: Any = 42
val str: String? = obj as? String // returns null
Kotlin中的集合类都是使用泛型实现的,例如List<T>
、Set<T>
、Map<K, V>
等。下面是一些示例:
val list: List<String> = listOf("one", "two", "three")
val set: Set<Int> = setOf(1, 2, 3)
val map: Map<String, Int> = mapOf("one" to 1, "two" to 2, "three" to 3)
可以使用filter
、map
等函数进行操作:
val list: List<Int> = listOf(1, 2, 3, 4, 5)
val filteredList: List<Int> = list.filter { it % 2 == 0 } // returns [2, 4]
val mappedList: List<String> = list.map { "Number $it" } // returns ["Number 1", "Number 2", "Number 3", "Number 4", "Number 5"]
Kotlin中泛型有一些限制,如不能使用基本数据类型作为泛型参数,只能使用封装类型。
Kotlin中的泛型系统可以帮助程序员编写更加安全和可重用的代码,提高代码的可读性和可维护性。
其中,类型投影和类型检查可以防止程序运行时出现类型错误,泛型在集合中的应用可以帮助程序员编写更加简洁和灵活的代码。