0Pricing
Kotlin Academy · 课时

使用处型变

类型投影

使用处型变 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。

使用处型变

有时,一个泛型类整体是不变型的,但某个具体函数只生成或只消费该类型。使用处型变(类型投影)会在使用类型的具体位置应用 out 或 in。

为什么使用使用处型变

像 MutableList<T> 这样的不变型类无法在声明处变为协变,因为它既会读取 T,也会写入 T。但是,某个具体函数可能只从中读取数据,而类型投影可以让我们安全地表达这一点。

out 投影

将 Array<out T> 写成参数类型会生成一个协变视图:您可以读取 T,但不能写入它。这样,在需要 Array<out Any> 的地方就可以传入 Array<String>。

fun printArray(items: Array<out Any>) {
    for (item in items) println(item)
}

fun main() {
    val names: Array<String> = arrayOf("Ann", "Bob")
    printArray(names)
}

仅供读取

使用 out 投影时,编译器允许读取(输出),但禁止写入(输入),因为写入可能会破坏原始数组的类型安全。

in 投影

将 Array<in T> 写成参数类型会生成一个逆变视图:您可以向其中写入 T,但读取到的值会被视为 Any?。这样,您就可以接受 T 的数组或任意超类型的数组。

fun fill(dest: Array<in Int>, value: Int) {
    for (i in dest.indices) dest[i] = value
}

fun main() {
    val numbers: Array<Number> = arrayOf(0, 0, 0)
    fill(numbers, 7)
    println(numbers.toList())
}

仅供写入

使用 in 投影时,您可以写入 T 类型的值(输入),但读取时元素类型会被视为顶层类型,因为实际元素类型可能是任意超类型。

投影与声明处型变

声明处型变(class Box<out T>)会应用于该类的所有使用位置。使用处投影(将 Box<out T> 作为参数)只应用于当前这一处。当类本身必须保持不变型时,请使用投影。

星投影

当您完全不关心类型参数时,请使用星投影 *。List<*>表示某种未知类型的列表;您可以将元素读取为上界类型,但无法安全地写入元素。

fun printSize(collection: List<*>) {
    println("Size: ${collection.size}")
}

fun main() {
    printSize(listOf(1, 2, 3))
    printSize(listOf("a", "b"))
}

星投影的限制

使用 * 时,您仍然可以调用与类型无关的成员(例如 size),并将元素读取为 Any?,但不能添加元素,因为实际类型是未知的。

fun main() {
    val unknown: List<*> = listOf("x", "y")
    val first: Any? = unknown.first()
    println(first)
}

选择投影方式

当函数只读取数据时使用 out T,只写入数据时使用 in T,而当具体类型无关紧要时使用 *。这些投影让不变类能够以灵活且类型安全的方式使用。

与 Java 通配符的关系

Kotlin 的 out T 和 in T 投影分别对应 Java 的 ? extends T 和 ? super T 通配符。如果您了解 Java 泛型,就会觉得投影很熟悉。

快速检查

对于类型为 Array<out Any> 的参数,您可以执行哪些操作?

回顾

使用处型变会在特定使用位置应用 out(只读)或 in(只写)投影,并在类型未知时使用 * 作为星投影。这样无需改变类的声明,就能让不变类更加灵活。接下来,您将学习如何使用泛型约束限制类型参数。

常见问题解答

「使用处型变」课时是免费的吗?

是的 — 「使用处型变」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。

「使用处型变」这节课中我会学到什么?

类型投影 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Kotlin Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用处型变」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Kotlin Academy 课中编写并运行代码吗?

能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 泛型函数与泛型类
  2. 声明处型变
  3. 使用处型变
  4. 泛型约束
← 返回 Kotlin Academy