Дорогие читатели,
Помогите сделать документацию лучше!

К сожалению текст все еще содержит некоторое количество ошибок, и мы просим вас найти и исправить их. Если бы каждый из посетителей исправил хотя бы одну ошибку, то мы смогли бы довести до совершенства весь материал всего за один день.


Основной синтаксис

Определение имени пакета

Имя пакета указывается в начале исходного файла, так же как и в Java:

package my.demo

import java.util.*

// ...

Но в отличие от Java, нет необходимости, чтобы структура пакетов совпадала со структурой папок: исходные файлы могут располагаться в произвольном месте на диске.

См. Пакеты.

Объявление функции

Функция принимает два аргумента Int и возвращает Int:

fun sum(a: Int, b: Int): Int {
  return a + b
}

Функция с выражением в качестве тела и автоматически определенным типом возвращаемого значения:

fun sum(a: Int, b: Int) = a + b

Функция, не возвращающая никакого значения (void в Java):

fun printSum(a: Int, b: Int): Unit {
  print(a + b)
}

Тип возвращаемого значения Unit может быть опущен:

fun printSum(a: Int, b: Int) {
  print(a + b)
}

См. Функции.

Определение внутренних переменных

Неизменяемая (только для чтения) внутренняя переменная:

val a: Int = 1
val b = 1   // Тип `Int` выведен автоматически
val c: Int  // Тип обязателен, когда значение не инициализируется
c = 1       // последующее присвоение

Изменяемая переменная:

var x = 5 // Тип `Int` выведен автоматически
x += 1

Глобальные переменные:

val PI = 3.14
var x = 0

fun incrementX() { 
    x += 1 
}

См. Свойства и поля.

Комментарии

Также, как Java и JavaScript, Kotlin поддерживает однострочные комментарии.

// однострочный комментарий

/* Блочный комментарий
   из нескольких строк. */

В отличие от Java, блочные комментарии могут быть вложенными.

См. Documenting Kotlin Code для информации о документации в комментариях.

Использование строковых шаблонов

Допустимо использование переменных внутри строк в формате $name или ${name}:

fun main(args: Array<String>) {
  if (args.size == 0) return

  print("Первый аргумент: ${args[0]}")
}
var a = 1
// просто имя переменной в шаблоне:
val s1 = "a is $a" 

a = 2
// произвольное выражение в шаблоне:
val s2 = "${s1.replace("is", "was")}, but now is $a"

/*
  Результат работы программы:
  a was 1, but now is 2
*/

См. Строковые шаблоны.

Использование условных выражений

fun max(a: Int, b: Int): Int {
  if (a > b)
    return a
  else
    return b
}

Также if может быть использовано как выражение (т. е. if ... else возвращает значение):

fun max(a: Int, b: Int) = if (a > b) a else b

См. Выражение if.

Nullable-значения и проверка на null

Ссылка должна быть явно объявлена как nullable (символ ?) когда она может принимать значение null.

Возвращает null если str не содержит числа:

fun parseInt(str: String): Int? {
  // ...
}

Использование функции, возвращающей null:

fun main(args: Array<String>) {
  if (args.size < 2) {
    print("Ожидается два целых числа")
    return
  }

  val x = parseInt(args[0])
  val y = parseInt(args[1])

  // Использование `x * y` приведет к ошибке, потому что они могут содержать null
  if (x != null && y != null) {
    // x и y автоматически приведены к не-nullable после проверки на null
    print(x * y)
  }
}

или

  // ...
  if (x == null) {
    print("Неверный формат числа у '${args[0]}'")
    return
  }
  if (y == null) {
    print("Неверный формат числа у '${args[1]}'")
    return
  }

  // x и y автоматически приведены к не-nullable после проверки на null
  print(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
}

См. Классы и Приведение типов.

Использование цикла for

fun main(args: Array<String>) {
  for (arg in args)
    print(arg)
}

или

for (i in args.indices)
  print(args[i])

См. цикл for.

Использование цикла while

fun main(args: Array<String>) {
  var i = 0
  while (i < args.size)
    print(args[i++])
}

См. цикл while.

Использование выражения when

fun cases(obj: Any) {
  when (obj) {
    1          -> print("One")
    "Hello"    -> print("Greeting")
    is Long    -> print("Long")
    !is String -> print("Not a string")
    else       -> print("Unknown")
  }
}

См. выражение when.

Использование интервалов

Проверка на вхождение числа в интервал с помощью оператора in:

if (x in 1..y-1)
  print("OK")

Проверка значения на выход за пределы интервала:

if (x !in 0..array.lastIndex)
  print("Out")

Перебор значений в заданном интервале:

for (x in 1..5)
  print(x)

Или по арифметической прогрессии:

for (x in 1..10 step 2) {
  print(x)
}
for (x in 9 downTo 0 step 3) {
  print(x)
}

См. Интервалы.

Использование коллекций

Итерация по коллекции:

for (name in names)
  println(name)

Проверка, содержит ли коллекция данный объект, с помощью оператора in:

val items = setOf("apple", "banana", "kiwi")
when {
  "orange" in items -> println("juicy")
  "apple" in items -> println("apple is fine too")
}

Использование лямбда-выражения для фильтрации и модификации коллекции:

names
    .filter { it.startsWith("A") }
    .sortedBy { it }
    .map { it.toUpperCase() }
    .forEach { print(it) }

См. Функции высшего порядка и лямбды.

Создание базовых классов и их экземпляров

val rectangle = Rectangle(5.0, 2.0) //не требуется ключевое слово 'new'
val triangle = Triangle(3.0, 4.0, 5.0)

См. Классы и Объявление экземпляров класса.