How do the indexing operators `a[i]` and `a[i] = v` map to functions, and how does Kotlin support multi-argument indexing like `matrix[r, c]`?
answer
- `a[i]` -> get, `a[i]=v` -> set
- Value is the LAST set() arg
- Multiple indices allowed: `get(r,c)`
- `a[i] += v` => set(i, get(i).plus(v))
- MutableMap/MutableList use get/set
basics
~10 sReading a[i] calls a.get(i). Writing a[i] = v calls a.set(i, v). You can pass several indices: a[r, c] calls get(r, c), and the value to store is always the last argument of set.
solid answer
~40 sThe index access operators map to `get` and `set` operator functions. `a[i]` -> `a.get(i)`; `a[i, j]` -> `a.get(i, j)` (any number of index args). For assignment, `a[i] = v` -> `a.set(i, v)` and `a[i, j] = v` -> `a.set(i, j, v)`: the assigned value is always passed as the **last** argument, the indices before it. Both must be declared `operator`. `get`/`set` can have any return types (though `set`'s return is ignored by the operator form). Augmented assignment like `a[i] += v` desugars to `a.set(i, a.get(i).plus(v))` when no `plusAssign` applies. This powers map-like syntax (`map["k"] = 1` calls `MutableMap.set`) and multi-dimensional containers. Because they're plain `operator` functions, they can be extensions, enabling indexed access on third-party types.
code
kotlin · 4 linesval grades = mutableMapOf<String, Int>()
grades["alice"] = 90 // grades.set("alice", 90)
val g = grades["alice"] // grades.get("alice")
grades["alice"] = (grades["alice"] ?: 0) + 5 // explicit read-modify-writego deeper
Knows [] maps to get/set and can use it on a map.
Implements multi-index get/set correctly with value-as-last-arg and explains map/list usage.
Explains augmented-assignment desugaring and the get-then-set read-modify-write cost, plus extension use.
Considers API ergonomics and pitfalls (double evaluation, thread-safety of read-modify-write) when designing indexed container APIs.
## The indexing operators Kotlin's square-bracket syntax is sugar for two operator functions: - **Read** — `a[i]` compiles to `a.get(i)`. - **Write** — `a[i] = v` compiles to `a.set(i, v)`. Both functions must be declared with the `operator` modifier and the reserved names `get` / `set`. ## Multi-argument indexing Kotlin allows **any number** of index arguments. The indices inside the brackets become the leading parameters: - `a[i, j]` -> `a.get(i, j)` - `a[i, j, k]` -> `a.get(i, j, k)` For `set`, the **assigned value is always the last parameter**, and the indices come first: - `a[i, j] = v` -> `a.set(i, j, v)` ```kotlin class Matrix(val rows: Int, val cols: Int) { private val data = IntArray(rows * cols) operator fun get(r: Int, c: Int): Int = data[r * cols + c] operator fun set(r: Int, c: Int, value: Int) { data[r * cols + c] = value } } val m = Matrix(2, 2) m[0, 1] = 5 // m.set(0, 1, 5) val x = m[0, 1] // m.get(0, 1) ``` ## Augmented assignment through indexing `a[i] += v` is convenient but has subtle desugaring. If no `plusAssign` is applicable, it becomes: ```kotlin a.set(i, a.get(i).plus(v)) ``` That means it reads the element, applies `plus`, and writes the result back — `get` is called **and** `set` is called. (If a `plusAssign` operator is present and applicable, `a.get(i).plusAssign(v)` is used instead, mutating in place.) ## Real-world usage The standard library uses these everywhere: - `MutableMap` defines `operator fun get` and `operator fun set`, so `map["k"] = 1` and `map["k"]` work. - `MutableList` has `get`/`set` for indexed access. - Arrays use intrinsic indexing backed by the same operator contract. ## Extensions Because `get`/`set` are ordinary `operator` functions, you can add bracket access to types you don't own: ```kotlin operator fun StringBuilder.get(range: IntRange) = substring(range.first, range.last + 1) ``` ## Return types `get` may return any type. `set` may declare a return type, but the operator form discards it — only the side effect matters.
- In `set`, which parameter holds the assigned value?The last parameter. Index arguments come first, the right-hand-side value is always passed last: `a[i, j] = v` -> `a.set(i, j, v)`.
- Does `a[i] += v` call both get and set?If no applicable `plusAssign`, yes: it desugars to `a.set(i, a.get(i).plus(v))`. With an applicable `plusAssign` it mutates in place via `a.get(i).plusAssign(v)`.
saying these in an interview costs you the question
- Saying the value is the first argument of `set`
- Thinking only single-index access is supported
- Not knowing `a[i] += v` can trigger both get and set
- Claiming `get`/`set` must be members (they can be extensions)