0Pricing
Kotlin Academy · 课时

索引与调用

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 反馈 — 无需本地设置。

此课程中的所有课时

  1. 运算符函数
  2. 比较运算符
  3. 索引与调用
  4. 最佳实践
← 返回 Kotlin Academy