Kotlin 泛型


Kotlin 泛型

Kotlin 作为一门现代化的编程语言,为了增强代码的可读性和复用性,支持泛型编程。本文将为大家详细介绍 Kotlin 泛型的概念、用法和相关技巧。

1. 什么是泛型

泛型(Generics)是指在编写代码时,使用一些特殊符号来表示不确定的类型,在使用时再指定具体的类型。泛型的优点在于可以让程序员编写更加通用、安全和可维护的代码。

2. 基本语法

在 Kotlin 中,使用尖括号 (<>) 来定义泛型参数,例如:

class Box<T>(t: T) {
    var value = t
}

在上述代码中, T 表示泛型参数。我们可以在创建对象时,传递不同类型的参数来创建不同的实例,例如:

val box1: Box<Int> = Box<Int>(1)
val box2: Box<String> = Box<String>("hello")

上述代码创建了两个 Box 的实例,分别存储了一个整数和一个字符串。注意,我们在创建时需要明确指定泛型参数的类型,即 Box<Int>Box<String>

2.1 多个泛型参数

Kotlin 还支持使用多个泛型参数。例如:

class Pair<K, V>(val first: K, val second: V) {
    // ...
}

在上述代码中,Pair 类具有两个泛型参数 KV,分别表示键和值的类型。在创建对象时,可以通过指定相应的类型来创建实例:

val pair1 = Pair(1, "one")
val pair2 = Pair("two", 2)

2.2 泛型约束

除了使用任意类型作为泛型参数外,还可以使用泛型约束来限制参数的类型范围。具体来说,我们可以使用 where 子句来指定某个参数必须是某种类型或实现了某个接口。例如:

fun <T> copyWhenGreater(list: List<T>, threshold: T): List<String>
    where T: CharSequence,
          T: Comparable<T> {
    // ...
}

在上述代码中,T 必须是一个可比较的字符序列。这样,我们将可以在方法内部使用 > 运算符来比较 thresholdlist 中的元素。

3. 泛型函数

Kotlin 除了支持泛型类之外,还支持泛型函数。在函数定义中,使用尖括号和类型参数来定义泛型函数。例如:

fun <T> List<T>.filter(predicate: (T) -> Boolean): List<T> {
    // ...
}

在上述代码中,filter 函数使用了类型参数 T,表示输入和输出集合的元素类型。predicate 参数则是一个函数类型的参数,其接收一个 T 类型的参数,并返回一个布尔值。

使用泛型函数时,可以显式指定类型参数,或者通过类型推断自动推断。例如:

val numbers = listOf(1, 2, 3, 4, 5)
val evenNumbers = numbers.filter { it % 2 == 0 }

在上述代码中,filter { it % 2 == 0 } 中的 it 参数被自动推断为 Int 类型,因此 T 被推断为 Int

4. 星号投影

在 Kotlin 中,使用星号(*)表示我们不知道参数的类型。这种形式被称为星号投影(Star Projection)。例如:

fun printList(list: List<*>) {
    // ...
}

在上述代码中,list 的元素类型可以是任意的。在函数内部,我们可以使用 Any 类型来操作所有元素,但是无法使用泛型参数的实际类型。

5. 总结

泛型是 Kotlin 中强大和常用的特性之一,使用泛型可以提高代码的复用性、安全性和可读性。本文中我们介绍了泛型类、泛型函数、泛型约束和星号投影等关键概念和语法。希望本文可以帮助大家更加深入地理解 Kotlin 泛型,并在实际应用中获得更好的效果。