Skip to content

Latest commit

 

History

History
388 lines (285 loc) · 10.5 KB

basic-syntax.md

File metadata and controls

388 lines (285 loc) · 10.5 KB
type layout category title url
doc
reference
Basics
Основной синтаксис

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

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

Имя пакета указывается в начале исходного файла, так же как и в 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, блочные комментарии могут быть вложенными.

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

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

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

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

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

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

/*
  Результат работы программы:
  a было равно 1, но теперь равно 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)

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