Индексация и вызов
get, set и invoke
«Индексация и вызов» — бесплатный урок Kotlin Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения 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])
}Запись с помощью set
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"])
}Оператор invoke
Определение operator fun invoke позволяет вызывать экземпляр как функцию: obj().
class Greeter(val name: String) {
operator fun invoke() = "Hello, $name"
}
fun main() {
val g = Greeter("Sam")
println(g())
}Вызов invoke с аргументами
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.- Операторы индекса поддерживают несколько ключей и ключи не только типа Int.
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"])
}Часто задаваемые вопросы
Урок «Индексация и вызов» бесплатный?
Да — полный текст урока «Индексация и вызов» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Kotlin Academy, подпишись на CoddyKit PRO. Курс Kotlin Academy содержит 4 уроков всего.
Чему я научусь в уроке «Индексация и вызов»?
get, set и invoke Ты практикуешь Kotlin Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Kotlin Academy?
Предыдущий опыт не требуется. Kotlin Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Индексация и вызов»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Kotlin Academy?
Да. Каждый урок Kotlin Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Функции-операторы
- Операторы сравнения
- Индексация и вызов
- Лучшие практики