Menu
Coddy logo textTech

Шпаргалка по Kotlin

Последнее обновление

Hello World и основы

Программа на Kotlin начинается с функции main верхнего уровня - класс не нужен.

СинтаксисЗначение
fun main() { println("Hello") }Точка входа программы
println("text")Вывести строку в стандартный вывод
print("text")Вывести без перевода строки в конце
// commentОднострочный комментарий
/* comment */Многострочный комментарий
val input = readLine()Прочитать строку из stdin (nullable String?)
val line = readln()Прочитать строку из stdin (non-null, Kotlin 1.6+)

Переменные (val / var) и типы

Предпочитайте val; берите var только когда значение должно меняться.

СинтаксисЗначение
val name = "Ada"Переменная только для чтения, тип выведен как String
var count = 0Изменяемая переменная
val age: Int = 30Явное указание типа
Int, Long, Double, FloatЧисловые типы (42, 42L, 3.14, 3.14f)
Boolean, Char, Stringtrue/false, 'a', "текст"
val big = 1_000_000Подчёркивания для читаемых литералов
"3".toInt(), "2.5".toDouble()Преобразовать строку в число
42.toString()Число в строку
const val MAX = 10Константа времени компиляции (на верхнем уровне или в object)

Строки и шаблоны

Строковые шаблоны почти везде заменяют конкатенацию.

СинтаксисЗначение
"Hi, $name"Вставить переменную в строку
"Total: ${price * qty}"Вставить выражение
s.lengthКоличество символов
s.uppercase(), s.lowercase()Изменить регистр
s.trim()Убрать пробелы в начале и в конце
s.contains("x"), s.startsWith("a")Поиск внутри строки
s.substring(0, 3)Срез по диапазону индексов
s.split(",")Разбить в List<String>
s[0]Символ по индексу
"""raw text"""Сырая многострочная строка без экранирования
"%.2f".format(3.14159)Форматированный вывод (3.14)

Null safety

Тип по умолчанию не допускает null; добавьте ?, чтобы разрешить null, и компилятор заставит его обработать.

СинтаксисЗначение
var s: String? = nullNullable-тип
s?.lengthБезопасный вызов - вернёт null, если s равно null
s?.length ?: 0Элвис-оператор - запасное значение при null
s!!.lengthУтверждение non-null - бросает исключение, если s равно null
if (s != null) s.lengthSmart cast к non-null внутри проверки
s?.let { println(it) }Выполнить блок только если не null
val n = s?.toIntOrNull()Разобрать или вернуть null при неверном вводе
lateinit var x: StringNon-null переменная, инициализируемая позже

Операторы

ОператорЗначение
+ - * / %Арифметика (/ для Int - целочисленное деление)
+= -= *= /= %=Составное присваивание
++ --Инкремент / декремент
== !=Структурное равенство (вызывает equals)
=== !==Ссылочное равенство (тот же объект)
< > <= >=Сравнение
&& || !Логические и / или / не
a in 1..10Принадлежность диапазону или коллекции
x as Int, x as? IntПриведение / безопасное приведение (null при неудаче)
x is StringПроверка типа (smart cast при успехе)

Управление потоком (if / when)

if и when - выражения, они возвращают значение.

СинтаксисЗначение
if (a > b) x else yif как выражение (в Kotlin нет тернарного ?:)
if (c) { ... } else if (d) { ... } else { ... }Цепочка ветвей
when (x) { 1 -> "one"; 2 -> "two"; else -> "other" }Сопоставить со значением
when (x) { 1, 2 -> "low" }Несколько значений в одной ветке
when (x) { in 1..9 -> "digit" }Сопоставить с диапазоном
when (x) { is String -> x.length }Сопоставить с типом (со smart cast)
when { x < 0 -> "neg"; x == 0 -> "zero"; else -> "pos" }when без субъекта, как if/else if
val label = when (x) { ... }when как выражение (нужен else)

Циклы и диапазоны

СинтаксисЗначение
for (i in 1..5)Включительный диапазон от 1 до 5
for (i in 1 until 5)От 1 до 4 (конец не включается)
for (i in 0..<5)То же с синтаксисом открытого диапазона (Kotlin 1.9+)
for (i in 10 downTo 1 step 2)Обратный отсчёт с шагом
for (item in list)Обойти коллекцию
for ((i, item) in list.withIndex())Индекс и элемент вместе
for (ch in "abc")Обойти символы строки
while (cond) { ... }Цикл, пока истинно
do { ... } while (cond)Выполнить хотя бы один раз
break, continueВыйти из цикла / перейти к следующей итерации
repeat(3) { println(it) }Выполнить блок n раз

Функции

СинтаксисЗначение
fun add(a: Int, b: Int): Int { return a + b }Объявить функцию
fun add(a: Int, b: Int) = a + bФункция из одного выражения, тип результата выводится
fun greet(name: String = "world")Значение параметра по умолчанию
greet(name = "Ada")Именованный аргумент
fun log(vararg items: String)Переменное число аргументов
fun say(): UnitБез возвращаемого значения (Unit можно опустить)
val square = { x: Int -> x * x }Лямбда в переменной
fun String.shout() = uppercase() + "!"Функция-расширение
fun apply(f: (Int) -> Int) = f(2)Функция как параметр
list.map { it * 2 }Trailing-лямбда, it - единственный параметр

Списки

listOf только для чтения; mutableListOf можно изменять.

СинтаксисЗначение
val nums = listOf(1, 2, 3)Список только для чтения
val items = mutableListOf("a")Изменяемый список
nums[0], nums.first(), nums.last()Доступ к элементам
nums.getOrNull(9)Безопасный доступ, null вне диапазона
items.add("b"), items.remove("a")Добавить / удалить
items[0] = "z"Заменить по индексу
nums.size, nums.isEmpty()Размер и пустота
x in nums, nums.contains(x)Принадлежность
nums.indexOf(2)Позиция элемента, -1 если его нет
nums.subList(0, 2)Срез (конец не включается)
nums.take(2), nums.drop(1)Первые n / все кроме первых n
nums.sorted(), nums.reversed()Новый отсортированный / перевёрнутый список
nums.sum(), nums.average(), nums.maxOrNull()Агрегаты
nums.joinToString(", ")Объединить в одну строку
Pair(1, "a"), 1 to "a", Triple(1, 2, 3)Маленькие кортежи фиксированного размера

Мапы и множества

СинтаксисЗначение
val m = mapOf("a" to 1, "b" to 2)Мапа только для чтения
val mm = mutableMapOf<String, Int>()Изменяемая мапа
m["a"]Поиск (null, если ключа нет)
m.getOrDefault("z", 0)Поиск с запасным значением
mm["c"] = 3Вставить или обновить
for ((k, v) in m)Обход записей с деструктуризацией
m.keys, m.valuesКоллекции ключей / значений
"a" in mНаличие ключа
val s = setOf(1, 2, 2)Множество уникальных значений ({1, 2})
mutableSetOf<Int>()Изменяемое множество

Операции над коллекциями (лямбды)

СинтаксисЗначение
list.map { it * 2 }Преобразовать каждый элемент
list.filter { it > 2 }Оставить подходящие элементы
list.forEach { println(it) }Сделать что-то с каждым
list.any { it > 2 }, list.all { it > 0 }Подходит ли хоть один / каждый элемент
list.count { it % 2 == 0 }Посчитать совпадения
list.find { it > 2 }Первое совпадение или null
list.sortedBy { it.length }Отсортировать по ключу
list.groupBy { it.first() }Сгруппировать в Map
list.distinct()Убрать дубликаты
list.fold(0) { acc, x -> acc + x }Свернуть с начальным значением
list.zip(other)Объединить два списка попарно
list.flatMap { it.toList() }Преобразовать и сгладить

Классы и data-классы

СинтаксисЗначение
class User(val name: String, var age: Int)Класс с первичным конструктором и свойствами
val u = User("Ada", 36)Создать экземпляр (без new)
u.name, u.age = 37Читать / записывать свойства
data class Point(val x: Int, val y: Int)equals, hashCode, toString, copy бесплатно
p.copy(y = 5)Копия с изменёнными свойствами
val (x, y) = pДеструктурирующее объявление
open class Base, class Sub : Base()Наследование (классы по умолчанию final)
override fun toString() = "..."Переопределить член
object Config { val debug = true }Синглтон
companion object { fun create() = User("", 0) }Аналог статических членов
enum class Color { RED, GREEN }Enum
sealed class ResultОграниченная иерархия классов, исчерпывающая в when
interface Shape { fun area(): Double }Интерфейс

Обработка ошибок

СинтаксисЗначение
try { ... } catch (e: Exception) { ... }Перехватить исключение
try { ... } finally { ... }Всегда выполнить очистку
val n = try { s.toInt() } catch (e: NumberFormatException) { 0 }try как выражение
throw IllegalArgumentException("bad")Бросить исключение
require(x > 0) { "x must be positive" }Проверка аргумента (бросает IllegalArgumentException)
check(ready) { "not ready" }Проверка состояния (бросает IllegalStateException)
s.toIntOrNull()Вернуть null вместо исключения
runCatching { risky() }.getOrDefault(0)Обернуть вызов в Result

Функции области видимости

Пять небольших помощников для работы с объектом внутри блока.

СинтаксисЗначение
x.let { it + 1 }it - объект, возвращает результат блока
x.run { this + 1 }this - объект, возвращает результат блока
x.apply { field = 1 }this - объект, возвращает объект
x.also { println(it) }it - объект, возвращает объект
with(x) { field }Не расширение; this - это x, возвращает результат блока
x?.let { ... }Идиоматичная проверка на null + использование

Весь синтаксис Kotlin, который вы ищете, на одной странице. Эта шпаргалка по Kotlin - краткий справочник по языку Android и значительной части современной JVM: объявление переменных, безопасная работа с null, ветвление через when, обход диапазонов, написание функций и работа со списками и мапами.

Всё здесь - стандартный Kotlin, одинаково работающий на JVM, в Android и в Kotlin Multiplatform. Копируйте нужное или пробуйте вживую в Kotlin-плейграунде: вставьте фрагмент, нажмите Run и посмотрите вывод в браузере.

Вопросы о шпаргалке по Kotlin

Эта шпаргалка по Kotlin бесплатна?
Да. Шпаргалка полностью бесплатна и не требует регистрации. Добавьте её в закладки и возвращайтесь, когда нужно вспомнить ветку when, оператор null safety или метод коллекции.
В чём разница между val и var в Kotlin?
val объявляет ссылку только для чтения: она присваивается один раз и не может быть переприсвоена. var объявляет изменяемую переменную, которую можно переприсваивать. Учтите, что val фиксирует только ссылку: в val list = mutableListOf(1) всё ещё можно добавлять элементы. Стиль Kotlin - использовать val везде и переходить на var только там, где переприсваивание действительно нужно.
Как работает null safety в Kotlin?
Типы по умолчанию не допускают null, поэтому String никогда не содержит null, а String? может. Компилятор не даст вызвать метод у nullable-значения без обработки случая null: безопасный вызов (s?.length), запасное значение через Элвис-оператор (s?.length ?: 0), проверка на null со smart cast (if (s != null)) или, в крайнем случае, утверждение s!!, которое бросает NullPointerException, если значение действительно null.
Когда использовать when вместо if в Kotlin?
Используйте when, когда сравниваете одно значение с несколькими вариантами - константами, диапазонами, типами или их смесью, а if/else - для одного условия да/нет. Оба являются выражениями, поэтому val label = when (x) { ... } и val label = if (c) a else b одинаково идиоматичны. when как выражение должен быть исчерпывающим, что обычно означает ветку else (sealed-классы и enum могут обходиться без неё).
Можно ли практиковаться в Kotlin онлайн?
Да. Откройте Kotlin-плейграунд и запустите любой фрагмент из этой шпаргалки в браузере - без установки JDK или IntelliJ. Когда захотите структуры, бесплатный интерактивный курс Kotlin от Coddy проведёт вас от Hello World через null safety, when, циклы, функции и коллекции и выдаст бесплатный сертификат в конце.
Coddy programming languages illustration

Изучайте Kotlin с Coddy

НАЧАТЬ