Kotlin 中的泛型:为何需要及如何使用:初学者指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Kotlin中的Generics:为什么需要以及如何使用



在使用Kotlin开发时,您经常需要编写能够处理不同数据类型的代码。与其为Int、String、Double等分别创建单独的函数或类,不如使用Generics(泛型)机制。本文将解释Kotlin中什么是Generics、为什么需要它们以及如何在实践中应用。



什么是Generics以及为什么需要它们?



Generics(泛型)是一种工具,允许您编写处理任意数据类型的类、接口和函数。想象一下,您创建了一个可以放入任何东西的盒子:书、手机或食物。与其为每个物品制作单独的盒子,不如制作一个通用的盒子。



使用Generics的主要优势:

  • 类型安全(Type Safety) — 编译器在编译阶段检查类型,从而防止运行时错误。
  • 代码复用 — 一次编写的代码可以处理任何类型。
  • 可读性 — 代码更加清晰,因为明确指出了它处理的是哪些类型。


没有Generics,您将不得不使用Any并不断进行类型转换,这容易导致错误。有了Generics,编译器会自动确保类型的正确性。



Kotlin中Generics的基础:类型参数



在Kotlin中,Generics通过类型参数实现。它们写在尖括号<>中。最常用的是字母T(Type)、E(Element)、K(Key)、V(Value),但您也可以使用任何名称。



泛型函数



从一个简单的例子开始——一个返回传入参数的函数:



fun <T> identity(value: T): T {    return value}

fun main() { val number: Int = identity(42) val text: String = identity("Привет") println(number) // 42 println(text) // Привет}


这里,函数名前的<T>声明了一个类型参数。类型T会根据参数自动推断,因此无需显式指定。



泛型类



类也可以是泛型的。让我们创建一个简单的容器:



class Box<T>(private val item: T) {    fun getItem(): T {        return item    }}

fun main() { val stringBox = Box("Книга") val intBox = Box(123)

println(stringBox.getItem()) // Книга println(intBox.getItem()) // 123}


Box<T>类可以存储任何类型的对象。创建实例时,我们指定具体类型,编译器保证getItem()返回的就是该类型。



类型约束(Type Bounds)



有时需要限制可以在泛型中使用的类型。例如,让函数只处理数字。为此,需要使用带有关键字:的约束(bounds)。



上界(Upper Bound)



fun <T : Number> sum(a: T, b: T): Double {    return a.toDouble() + b.toDouble()}

fun main() { println(sum(10, 20)) // 30.0 println(sum(3.5, 2.5)) // 6.0 // println(sum("A", "B")) // 编译错误}


这里的T : Number表示类型T必须是Number类的子类。Int、Double、Float符合条件,而String则不行。



多重约束



如果需要多个约束,请使用where:



interface Printable {    fun print()}

fun <T>

博客

书籍推荐