📜  Kotlin泛型(1)

📅  最后修改于: 2023-12-03 15:32:31.543000             🧑  作者: Mango

Kotlin泛型简介

在面向对象编程中,泛型是指编写能够适用于多种数据类型的代码,使得代码更加通用且可读性更强。Kotlin具有一套独特的泛型系统,可以帮助程序员编写更加安全和可重用的代码。

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类型投影

Kotlin中类型投影分为三种:

1. 协变(Covariant)

协变是指如果AB的子类型,则List<A>List<B>的子类型,可以使用out关键字使得类型成为协变:

interface Producer<out T> {
    fun produce(): T
}

fun demo(strProducer: Producer<String>) {
    val anyProducer: Producer<Any> = strProducer
}
2. 逆变(Contravariant)

逆变是指如果AB的子类型,则List<B>List<A>的子类型,可以使用in关键字使得类型成为逆变:

interface Consumer<in T> {
    fun consume(item: T)
}

fun demo(anyConsumer: Consumer<Any>) {
    val strConsumer: Consumer<String> = anyConsumer
}
3. 不变(Invariant)

不变是指如果A不是B的子类型,那么List<A>List<B>是没有任何关系的。

Kotlin类型检查与类型转换

Kotlin中的is关键字可以用来检查一个对象的类型,如果对象的类型是指定类型的子类型,那么返回true,否则返回falseas?操作符可以用来将对象转换为指定类型,如果对象不是指定类型的子类型,那么返回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泛型在集合中的应用

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)

可以使用filtermap等函数进行操作:

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中泛型有一些限制,如不能使用基本数据类型作为泛型参数,只能使用封装类型。

Kotlin泛型的优势

Kotlin中的泛型系统可以帮助程序员编写更加安全和可重用的代码,提高代码的可读性和可维护性。

其中,类型投影和类型检查可以防止程序运行时出现类型错误,泛型在集合中的应用可以帮助程序员编写更加简洁和灵活的代码。