Обзор основного синтаксиса
Это подборка базового синтаксиса с примерами. В конце каждого раздела вы найдете ссылку на более подробное описание соответствующей темы.
Вы также можете изучить все основы Kotlin в бесплатном курсе Kotlin Core от JetBrains Academy.
Определение имени пакета и импорт
Имя пакета должно указываться в начале исходного файла:
package my.demo
import kotlin.text.*
// ...
Сопоставлять каталоги и пакеты не обязательно: исходные файлы могут располагаться в произвольном месте в файловой системе.
См. Пакеты.
Точка входа в программу
В Kotlin точкой входа в программу является функция main.
fun main() {
println("Hello world!")
}
Другая форма main принимает переменное количество аргументов типа String.
fun main(args: Array<String>) {
println(args.contentToString())
}
Вывод в стандартный поток
print выводит свой аргумент в стандартный поток вывода.
print("Hello ")
print("world!")
println выводит свой аргумент и добавляет перевод строки, так что следующее, что вы выведите, появится на следующей строке.
println("Hello world!")
println(42)
Чтение из стандартного потока ввода
Функция readln() читает данные из стандартного потока ввода.
Она считывает всю введенную пользователем строку как строковое значение.
Функции println(), readln() и print() можно использовать вместе, чтобы выводить запросы на ввод
и показывать введенные пользователем данные:
// Выводит сообщение с запросом на ввод
println("Введите любое слово: ")
// Читает и сохраняет пользовательский ввод. Например: Счастье
val yourWord = readln()
// Выводит сообщение с введенным значением
print("Вы ввели слово: ")
print(yourWord)
// Вы ввели слово: Счастье
Подробнее см. Чтение стандартного ввода.
Функции
Функция с двумя параметрами типа Int и возвращаемым значением типа Int.
fun sum(a: Int, b: Int): Int {
return a + b
}
В качестве тела функции может выступать выражение. Тогда тип возвращаемого значения определяется автоматически.
fun sum(a: Int, b: Int) = a + b
Функция, которая не возвращает осмысленного значения.
fun printSum(a: Int, b: Int): Unit {
println("сумма $a и $b равна ${a + b}")
}
Тип возвращаемого значения Unit может быть опущен.
fun printSum(a: Int, b: Int) {
println("сумма $a и $b равна ${a + b}")
}
См. Функции.
Переменные
В Kotlin объявление переменной начинается с ключевого слова val или var, после которого указывается имя переменной.
Используйте ключевое слово val для объявления переменных, которым значение присваивается только один раз.
Это неизменяемые локальные переменные только для чтения: после инициализации им нельзя присвоить другое значение.
val x: Int = 5
Используйте ключевое слово var для объявления переменных, которым можно присваивать новые значения.
Это изменяемые переменные: их значения можно менять после инициализации.
var x: Int = 5
x += 1
Kotlin поддерживает вывод типов и автоматически определяет тип данных объявленной переменной. При объявлении переменной можно опустить тип после ее имени.
val x = 5
Переменные можно использовать только после инициализации. Переменную можно инициализировать в момент объявления или сначала объявить, а затем инициализировать позже. Во втором случае тип данных нужно указывать явно.
val x = 5
val c: Int
c = 3
Вы можете объявлять переменные на верхнем уровне.
val PI = 3.14
var x = 0
fun incrementX() {
x += 1
}
Информацию об объявлении свойств см. в разделе Свойства.
Создание классов и экземпляров
Чтобы определить класс, используйте ключевое слово class.
class Shape
Свойства класса могут быть перечислены при его объявлении или в его теле.
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
Конструктор по умолчанию с параметрами, перечисленными при объявлении класса, доступен автоматически.
class Rectangle(val height: Double, val length: Double) {
val perimeter = (height + length) * 2
}
val rectangle = Rectangle(5.0, 2.0)
println("Периметр равен ${rectangle.perimeter}")
Чтобы объявить наследование между классами используйте двоеточие (:). По умолчанию классы являются финальными,
поэтому, чтобы сделать класс наследуемым, используйте open.
open class Shape
class Rectangle(val height: Double, val length: Double): Shape() {
val perimeter = (height + length) * 2
}
Подробнее о конструкторах и наследовании см. в разделах Классы и Объекты и экземпляры.
Комментарии
Как и большинство современных языков, Kotlin поддерживает однострочные (до конца строки) и многострочные (блочные) комментарии.
// Это однострочный комментарий
/* Это блочный комментарий
из нескольких строк. */
Блочные комментарии в Kotlin могут быть вложенными.
/* Этот комментарий начинается здесь
/* содержит вложенный комментарий */
и заканчивается здесь. */
См. Документация Kotlin кода для информации о документации в комментариях.
Строковые шаблоны
fun main() {
var a = 1
// простое имя в шаблоне:
val s1 = "a равно $a"
a = 2
// произвольное выражение в шаблоне:
val s2 = "${s1.replace("равно", "было равно")}, но теперь равно $a"
println(s2)
}
См. Строковые шаблоны.
Условные выражения
fun maxOf(a: Int, b: Int): Int {
if (a > b) {
return a
} else {
return b
}
}
В Kotlin if также может использоваться как выражение:
fun maxOf(a: Int, b: Int) = if (a > b) a else b
См. Выражение if.
Цикл for
val items = listOf("яблоко", "банан", "киви")
for (item in items) {
println(item)
}
или
val items = listOf("яблоко", "банан", "киви")
for (index in items.indices) {
println("элемент с индексом $index - это ${items[index]}")
}
См. Цикл for.
Цикл while
val items = listOf("яблоко", "банан", "киви")
var index = 0
while (index < items.size) {
println("элемент с индексом $index - это ${items[index]}")
index++
}
См. Цикл while.
Выражение when
fun describe(obj: Any): String =
when (obj) {
1 -> "Один"
"Hello" -> "Приветствие"
is Long -> "Long"
!is String -> "Не строка"
else -> "Неизвестно"
}
См. Выражения и инструкции when.
Интервалы
Проверка на вхождение числа в интервал с помощью оператора in.
val x = 10
val y = 9
if (x in 1..y+1) {
println("попадает в диапазон")
}
Проверка значения на выход за пределы интервала.
val list = listOf("a", "b", "c")
if (-1 !in 0..list.lastIndex) {
println("-1 вне диапазона")
}
if (list.size !in list.indices) {
println("размер списка тоже вне допустимого диапазона индексов")
}
Перебор значений в заданном интервале.
for (x in 1..5) {
print(x)
}
Или по арифметической прогрессии.
for (x in 1..10 step 2) {
print(x)
}
println()
for (x in 9 downTo 0 step 3) {
print(x)
}
Коллекции
Итерация по коллекции.
for (item in items) {
println(item)
}
Проверка, содержит ли коллекция данный объект, с помощью оператора in.
val items = setOf("яблоко", "банан", "киви")
when {
"апельсин" in items -> println("сочно")
"яблоко" in items -> println("яблоко тоже подойдет")
}
Используйте лямбда-выражения, чтобы фильтровать и преобразовывать коллекции.
val fruits = listOf("банан", "авокадо", "яблоко", "киви")
fruits
.filter { it.startsWith("а") }
.sortedBy { it }
.map { it.uppercase() }
.forEach { println(it) }
См. Коллекции.
Nullable-значения и проверка на null
Ссылка должна быть явно помечена как nullable, когда для нее возможно значение null.
Имена nullable-типов заканчиваются символом ?, например Int?.
Возвращает null, если str не содержит целое число.
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
Использование функции, возвращающей nullable-значение.
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// Использование `x * y` приведет к ошибке, потому что они могут содержать null.
if (x != null && y != null) {
// x и y автоматически приведены к не-nullable после проверки на null
println(x * y)
}
else {
println("'$arg1' или '$arg2' не является числом")
}
}
или
fun parseInt(str: String): Int? {
return str.toIntOrNull()
}
fun printProduct(arg1: String, arg2: String) {
val x = parseInt(arg1)
val y = parseInt(arg2)
// ...
if (x == null) {
println("Неверный формат числа в arg1: '$arg1'")
return
}
if (y == null) {
println("Неверный формат числа в arg2: '$arg2'")
return
}
// x и y автоматически приведены к не-nullable после проверки на null
println(x * y)
}
См. Null-безопасность.
Проверка типа и автоматическое приведение типов
Оператор is проверяет, является ли выражение экземпляром заданного типа.
Если неизменяемая локальная переменная или свойство уже проверены на определенный тип, то в дальнейшем нет необходимости
явно приводить к этому типу:
fun getStringLength(obj: Any): Int? {
if (obj is String) {
// в этой ветке `obj` автоматически преобразован в `String`
return obj.length
}
// вне ветки проверки типа `obj` по-прежнему имеет тип `Any`
return null
}
или
fun getStringLength(obj: Any): Int? {
if (obj !is String) return null
// в этой ветке `obj` автоматически преобразован в `String`
return obj.length
}
или даже
fun getStringLength(obj: Any): Int? {
// `obj` автоматически преобразован в `String` справа от оператора `&&`
if (obj is String && obj.length >= 0) {
return obj.length
}
return null
}
См. Классы и Приведение типов.