使用处型变
类型投影
使用处型变 是 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 反馈 — 无需本地设置。