索引与调用
get、set 与 invoke
索引与调用 是 CoddyKit 上的免费 Kotlin Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Kotlin Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Kotlin Academy 课程共包含 4 节课。
索引运算符
定义 operator fun get 后,就可以使用方括号语法读取数据:obj[i]。
class Row(val cells: List<String>) {
operator fun get(i: Int) = cells[i]
}
fun main() {
val r = Row(listOf("a", "b", "c"))
println(r[1])
}使用索引写入
operator fun set 支持赋值:obj[i] = value。最后一个参数就是要写入的值。
class Grid {
private val data = IntArray(3)
operator fun get(i: Int) = data[i]
operator fun set(i: Int, value: Int) { data[i] = value }
}
fun main() {
val g = Grid()
g[0] = 42
println(g[0])
}多参数索引
get 和 set 可以接受多个索引,非常适合用于矩阵。
class Matrix {
private val d = Array(2) { IntArray(2) }
operator fun get(r: Int, c: Int) = d[r][c]
operator fun set(r: Int, c: Int, v: Int) { d[r][c] = v }
}
fun main() {
val m = Matrix()
m[1, 1] = 9
println(m[1, 1])
}使用非 Int 键进行索引
索引参数可以是任意类型,从而支持类似映射的访问方式。
class Settings {
private val map = mutableMapOf<String, String>()
operator fun get(key: String) = map[key]
operator fun set(key: String, value: String) { map[key] = value }
}
fun main() {
val s = Settings()
s["theme"] = "dark"
println(s["theme"])
}调用运算符
定义 operator fun invoke 后,就可以像调用函数一样调用实例:obj()。
class Greeter(val name: String) {
operator fun invoke() = "Hello, $name"
}
fun main() {
val g = Greeter("Sam")
println(g())
}带参数调用
invoke 可以接受参数,使对象表现得像一个带参数的函数。
class Multiplier(val factor: Int) {
operator fun invoke(x: Int) = x * factor
}
fun main() {
val triple = Multiplier(3)
println(triple(5))
}有状态的可调用对象
由于对象持有状态,invoke 可以构建可配置的类函数对象。
class Accumulator {
var total = 0
operator fun invoke(n: Int) { total += n }
}
fun main() {
val acc = Accumulator()
acc(5)
acc(10)
println(acc.total)
}多个调用重载
您可以使用不同的参数声明多个 invoke 重载。
class Printer {
operator fun invoke(s: String) = println(s)
operator fun invoke(n: Int) = println("num: $n")
}
fun main() {
val p = Printer()
p("hi")
p(7)
}表达式中的索引访问
索引访问可以自然地与其他操作组合。
class Scores(private val list: List<Int>) {
operator fun get(i: Int) = list[i]
}
fun main() {
val s = Scores(listOf(10, 20, 30))
println(s[0] + s[2])
}结合获取和调用
一种类型可以同时支持索引和调用,从而提供表达力更强的接口。
class Lookup(private val data: Map<String, Int>) {
operator fun get(key: String) = data[key]
operator fun invoke() = data.size
}
fun main() {
val l = Lookup(mapOf("a" to 1))
println(l["a"])
println(l())
}标准库如何使用它
列表的 list[i] 和映射的 map[key] 正是这些运算符。您也可以让自己的类型使用起来同样自然。
fun main() {
val list = listOf(1, 2, 3)
val map = mapOf("x" to 9)
println(list[0])
println(map["x"])
}快速检查
请检验您对索引访问和调用的理解。
回顾
您学会了索引访问和调用:
get支持obj[i];set支持obj[i] = v。- 索引运算符支持多个键,也支持非整数键。
invoke让实例可以像函数一样被调用,无论是否带参数。- 标准集合正是使用这些运算符。
class Box {
private val m = mutableMapOf<String, Int>()
operator fun get(k: String) = m[k]
operator fun set(k: String, v: Int) { m[k] = v }
}
fun main() {
val b = Box()
b["x"] = 5
println(b["x"])
}常见问题解答
「索引与调用」课时是免费的吗?
是的 — 「索引与调用」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Kotlin Academy 课程的其余内容,请升级到 CoddyKit PRO。 Kotlin Academy 课程共包含 4 节课。
「索引与调用」这节课中我会学到什么?
get、set 与 invoke 你通过在浏览器中直接运行的动手代码来练习 Kotlin Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Kotlin Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Kotlin Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。
「索引与调用」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Kotlin Academy 课中编写并运行代码吗?
能。每节 Kotlin Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。