Содержание
Основной синтаксис — Kotlin
Это подборка базового синтаксиса с примерами.
В конце каждого раздела вы найдете ссылку на более подробное описание соответствующей темы.
Вы также можете изучить все основы Kotlin в бесплатном курсе Основы Kotlin от JetBrains Academy.
Определение имени пакета и импорт
Имя пакета указывается в начале исходного файла, так же как и в Java.
package my.demo import java.util.* // ...
Но в отличие от Java, нет необходимости, чтобы структура пакетов совпадала со структурой папок:
исходные файлы могут располагаться в произвольном месте на диске.
См. Пакеты.
Точка входа в программу
В 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)
Функции
Функция принимает два аргумента 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 { println("сумма $a и $b равна ${a + b}") }
Тип возвращаемого значения Unit
может быть опущен.
fun printSum(a: Int, b: Int) { println("сумма $a и $b равна ${a + b}") }
См. Функции.
Переменные
Неизменяемые (только для чтения) локальные переменные определяются с помощью ключевого слова val
. Присвоить им значение можно только один раз.
val a: Int = 1 // Инициализация при объявлении val b = 1 // Тип `Int` определен автоматически val c: Int // Указывать тип обязательно, если переменная не инициализирована сразу c = 1 // Последующее присвоение
Изменяемые переменные объявляются с помощью ключевого слова var
.
var x = 5 // Тип `Int` определен автоматически x += 1
Вы можете объявлять глобальные переменные.
val PI = 3.14 var x = 0 fun incrementX() { x += 1 }
См. Свойства и поля.
Создание классов и экземпляров
Для создания класса используйте ключевое слово class
.
class Shape
Свойства класса могут быть перечислены при его объявлении или в его теле.
class Rectangle(var height: Double, var length: Double) { var perimeter = (height + length) * 2 }
Конструктор по умолчанию с параметрами, перечисленными при объявлении класса, доступен автоматически.
val rectangle = Rectangle(5.0, 2.0) println("Периметр равен ${rectangle.perimeter}")
Чтобы объявить наследование между классами используйте двоеточие (:
). По умолчанию классы являются финальными,
поэтому, чтобы сделать класс наследуемым, используйте open
.
open class Shape class Rectangle(var height: Double, var length: Double): Shape() { var perimeter = (height + length) * 2 }
См. Классы и наследование и Объекты и экземпляры.
Комментарии
Также, как любой другой популярный современный язык, Kotlin поддерживает однострочные и многострочные (блочные) комментарии.
// Это однострочный комментарий /* Это блочный комментарий из нескольких строк. */
Блочные комментарии в Kotlin могут быть вложенными.
/* Этот комментарий начинается здесь /* содержит вложенный комментарий */ и заканчивается здесь. */
См. Документация 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 maxOf(a: Int, b: Int): Int { if (a > b) { return a } else { return b } }
В Kotlin if
может быть использован как выражение (т. е. if
… else
возвращает значение):
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 -> "Unknown" }
См. Выражение 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("сочно") "apple" in items -> println("яблоко тоже подойдет") }
Использование лямбда-выражения для фильтрации и модификации коллекции.
val fruits = listOf("банан", "авокадо", "яблоко", "киви") fruits .filter { it.startsWith("а") } .sortedBy { it } .map { it.uppercase() } .forEach { println(it) }
См. Коллекции.
Nullable-значения и проверка на null
Ссылка должна быть явно объявлена как nullable (символ ?
в конце имени), когда она может принимать значение null
.
Возвращает null
, если str
не содержит числа.
fun parseInt(str: String): Int? { // ... }
Использование функции, возвращающей null
.
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 print(x * y) } else { println("'$arg1' или '$arg2' не число") } }
или
// ... if (x == null) { print("Неверный формат числа arg1: '$arg1'") return } if (y == null) { print("Неверный формат числа arg2: '$arg2'") 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 }
См. Классы и Приведение типов.
Классы — Kotlin
Классы в Kotlin объявляются с помощью использования ключевого слова class
.
class Person { /*. ..*/ }
Объявление класса состоит из имени класса, заголовка (указания типов его параметров, основного конструктора и т.п) и тела класса,
заключённого в фигурные скобки. И заголовок, и тело класса являются необязательными составляющими. Если у класса нет тела, фигурные скобки могут быть опущены.
class Empty
Конструкторы
Класс в Kotlin может иметь основной конструктор (primary constructor) и один или более дополнительных конструкторов (secondary constructors).
Основной конструктор является частью заголовка класса, его объявление идёт сразу после имени класса (и необязательных параметров).
class Person constructor(firstName: String) { /*...*/ }
Если у основного конструктора нет аннотаций и модификаторов видимости, ключевое слово constructor
может быть опущено.
class Person(firstName: String) { /*...*/ }
Основной конструктор не может содержать в себе исполняемого кода. Инициализирующий код может быть помещён в соответствующие блоки (initializers blocks),
которые помечаются словом init
.
При создании экземпляра класса блоки инициализации выполняются в том порядке, в котором они идут в теле класса, чередуясь с инициализацией свойств.
class InitOrderDemo(name: String) { val firstProperty = "Первое свойство: $name".also(::println) init { println("Первый блок инициализации: ${name}") } val secondProperty = "Второе свойство: ${name.length}".also(::println) init { println("Второй блок инициализации: ${name.length}") } }
Обратите внимание, что параметры основного конструктора могут быть использованы в инициализирующем блоке.
Они также могут быть использованы при инициализации свойств в теле класса.
class Customer(name: String) { val customerKey = name.uppercase() }
Для объявления и инициализации свойств основного конструктора в Kotlin есть лаконичное синтаксическое решение:
class Person(val firstName: String, val lastName: String, var age: Int)
Такие объявления также могут включать в себя значения свойств класса по умолчанию.
class Person(val firstName: String, val lastName: String, var isEmployed: Boolean = true)
Вы можете использовать завершающую запятую при объявлении свойств класса.
class Person( val firstName: String, val lastName: String, var age: Int, // завершающая запятая ) { /*...*/ }
Свойства, объявленные в основном конструкторе, могут быть изменяемые (var
) и неизменяемые (val
).
Если у конструктора есть аннотации или модификаторы видимости, ключевое слово constructor
обязательно, и модификаторы используются перед ним.
class Customer public @Inject constructor(name: String) { /*...*/ }
Для более подробной информации см. «Модификаторы доступа».
Дополнительные конструкторы
В классах также могут быть объявлены дополнительные конструкторы (secondary constructors), перед которыми используется ключевое слово constructor
.
class Person(val pets: MutableList<Pet> = mutableListOf()) class Pet { constructor(owner: Person) { owner. pets.add(this) // добавляет этого питомца в список домашних животных своего владельца } }
Если у класса есть основной конструктор, каждый дополнительный конструктор должен прямо или косвенно ссылаться (через другой(ие) конструктор(ы)) на основной.
Осуществляется это при помощи ключевого слова this
.
class Person(val name: String) { val children: MutableList<Person> = mutableListOf() constructor(name: String, parent: Person) : this(name) { parent.children.add(this) } }
Обратите внимание, что код в блоках инициализации фактически становится частью основного конструктора.
Дополнительный конструктор ссылается на основной при помощи своего первого оператора, поэтому код во всех блоках инициализации,
а также инициализация свойств выполняется перед выполнением кода в теле дополнительного конструктора.
Даже если у класса нет основного конструктора на него все равно происходит неявная ссылка и блоки инициализации выполняются также.
class Constructors { init { println("Блок инициализации") } constructor(i: Int) { println("Constructor $i") } }
Если в абстрактном классе не объявлено никаких конструкторов (основного или дополнительных), у этого класса автоматически сгенерируется пустой конструктор без параметров.
Видимость этого конструктора будет public.
Если вы не желаете иметь класс с открытым public конструктором, вам необходимо объявить пустой конструктор с соответствующим модификатором видимости.
class DontCreateMe private constructor () { /*...*/ }
В JVM компилятор генерирует дополнительный конструктор без параметров в случае, если все параметры основного конструктора имеют значения по умолчанию. Это делает использование таких библиотек, как Jackson и JPA, более простым с Kotlin, так как они используют пустые конструкторы при создании экземпляров классов.
class Customer(val customerName: String = "")
Создание экземпляров классов
Для создания экземпляра класса конструктор вызывается так, как если бы он был обычной функцией.
val invoice = Invoice() val customer = Customer("Joe Smith")
В Kotlin нет ключевого слова
new
.
Создание экземпляров вложенных, внутренних и анонимных внутренних классов описано в разделе Вложенные классы.
Члены класса
Классы могут содержать в себе:
- Конструкторы и инициализирующие блоки
- Функции
- Свойства
- Вложенные классы
- Объявления объектов
Наследование
Классы могут быть производными друг от друга и формировать иерархии наследования.
Узнайте больше о наследовании в Котлине.
Абстрактные классы
Класс может быть объявлен как abstract
со всеми или некоторыми его членами. Абстрактный член не имеет реализации в своём классе.
Обратите внимание, что нам не надо аннотировать абстрактный класс или функцию словом open
— это и так подразумевается.
abstract class Polygon { abstract fun draw() } class Rectangle : Polygon() { override fun draw() { // рисование прямоугольника } }
Можно переопределить неабстрактный open
член абстрактным.
open class Polygon { open fun draw() { // некоторый метод рисования полигонов по умолчанию } } abstract class WildShape : Polygon() { // Классы, которые наследуют WildShape, должны предоставлять свой собственный // метод рисования вместо использования по умолчанию для полигона abstract override fun draw() }
Вспомогательные объекты
Если вам нужно написать функцию, которая может быть использована без создания экземпляра класса, имеющую доступ к данным внутри этого класса
(к примеру, фабричный метод), вы можете написать её как член объявления объекта внутри этого класса.
В частности, если вы объявляете вспомогательный объект в своём классе,
у вас появляется возможность обращаться к членам класса, используя только название класса в качестве классификатора.
Язык программирования Котлин
Начать
Разработано JetBrains
и участники с открытым исходным кодом
Мультиплатформенный
Делитесь кодом на своих условиях и для разных платформ
На стороне сервера
Современный опыт разработки с использованием знакомой технологии JVM
Мультиплатформенные библиотеки
Создайте библиотеку, которая работает на нескольких платформах
Андроид
Рекомендуется Google для создания приложений для Android
Наука о данных
Простой
Асинхронный
Объектно-ориентированный
Функциональный
Идеально подходит для тестов
5"> веселая главная () { val name = "stranger" // Объявите вашу первую переменную println("Привет, $name!") // ...и пользуйся! print("Текущее количество:") for (i in 0..10) { // Цикл в диапазоне от 0 до 10 распечатать("$я") } }импортировать kotlinx.coroutines.* suspend fun main() { // Функция, которую можно приостановить и возобновить позже val start = System.currentTimeMillis() coroutineScope { // Создаем область для запуска сопрограмм для (я в 1..10) { launch { // Запустить 10 одновременных задач delay(3000L - i * 300) // Приостановить их выполнение log(начало, "Обратный отсчет: $i") } } } // Выполнение продолжается после завершения всех сопрограмм в области видимости log(начало, "Взлет!") } журнал развлечений (начало: длинное, сообщение: строка) { println("$msg" + "(на ${Thread. currentThread().name}) " + "после ${(System.currentTimeMillis() - start)/1000F} с") }
абстрактный класс Person (имя val: String) { абстрактное веселое приветствие () } интерфейс FoodConsumer { весело есть () fun pay(amount: Int) = println("Вкусно! Вот $amount баксов!") } класс RestaurantCustomer (имя: строка, значение блюда: строка): человек (имя), FoodConsumer { fun order() = println("$dish, пожалуйста!") переопределить fun eat() = println("*Ест $блюдо*") переопределить fungreet() = println("Это я, $name.") } веселая главная () { val sam = RestaurantCustomer("Сэм", "Салат") sam.greet() // Реализация абстрактной функции sam.order() // Функция-член sam.eat() // Реализация функции интерфейса sam.pay(10) // Реализация по умолчанию в интерфейсе }5"> веселая главная () { // Кто отправил больше всего сообщений? val FreightSender = сообщения .groupBy(Сообщение::отправитель) .maxByOrNull { (_, сообщения) -> messages.size } ?.key // Получить их имена println(frequentSender) // [Ма] // Кто отправители? val отправители = сообщения .asSequence() // Делаем операции ленивыми (для длинной цепочки вызовов) .filter { it.body.isNotBlank() && !it.isRead } // Использовать лямбда-выражения... .map(Message::sender) // ...или ссылки на элементы .отчетливый() .сортировано() .toList() // Преобразование последовательности обратно в список для получения результата println(senders) // [Адам, Ма] } Сообщение класса данных( // Создаем класс данных val отправитель: строка, тело val: Строка, val isRead: Boolean = false, // Предоставляем значение по умолчанию для аргумента ) val messages = listOf( // Создаем список Сообщение("Ма", "Эй! Где ты?"), Message("Адам", "Сегодня все идет по плану?"), Сообщение("Ма", "Пожалуйста, ответьте. Я вас потеряла!"), )
// Тесты // Следующий пример работает только для JVM импортировать org.junit.Test импортировать kotlin.test.* класс SampleTest { @Тест fun `test sum`() { // Пишем имена тестов с пробелами в обратных кавычках значение а = 1 знач б = 41 assertEquals(42, sum(a, b), "Неверный результат для суммы($a, $b)") } @Тест весело `проверить вычисление`() { assertTrue("Ошибка вычисления") { setup() // Используем лямбду, возвращающую испытуемый вычислить() } } } // Источники забавная сумма (a: Int, b: Int) = a + b забавная установка () {} весело вычислить () = правда
Начать ↗
Краткий
Выразительный
Асинхронный
Совместимый
5"> // Более чем на 30% меньше строк кода по сравнению с Java // (на основе опыта Duolingo и других компаний) класс данных Книга ( val title: String, // + автоматически генерируется equals(), val year: Int // hashCode(), toString() и copy() ) fun Century(year: Int) = (year - 1) / 100 + 1 // Функция верхнего уровня, // тело одного выражения веселая главная () { val books = listOf( // Создаем список Book("Дон Кихот", 1605), // Нет ключевого слова `new` Книга("Властелин колец", 1955) ) val classics = books.filter { век(it.year)// Приложения, созданные с помощью Kotlin, на 20% реже вылетают // (на основе внутренних данных Google) fun printMessagesUppercased(messages: List) { // Элементы списка могут быть пустыми // messages.add(Message("Java")) // ОШИБКА: Список доступен только для чтения messages. onEachIndexed {индекс, сообщение -> print("\nСообщение #$index: ") // print(msg.uppercase()) // ОШИБКА: `msg` может быть нулевым msg?.let { // Печатать, только если `msg` не равно null print(it.uppercase()) // ОК, это строка } } } веселая главная () { val messages = mutableListOf («привет», null, «мир») // messages = mutableListOf("!!!") // ОШИБКА: невозможно переназначить значение messages.add("Kotlin") // ОК: список можно изменять printMessagesUppercased(messages) // Передать список только для чтения }
импортировать kotlin.math.absoluteValue веселая главная () { // начало выборки val dates = listOf (от 1 до «января», от 13 до «мая», от 22 до «сентября», от 23 до «декабря») date.forEach { (день, месяц) -> // Проходим список пар с завершающей лямбдой println("${day.ordinal()} of $month") // Использовать функцию расширения Int. ordinal() } создатьпустое окно() .apply { // Настраиваем свойства объекта ширина = 300 высота = 200 Видимый = Истина }.also { w -> // Выполняем дополнительную операцию над цепочкой вызовов показатьокно(ж) } issueById["13456"] ?.takeIf { it.status == Status.FIXED } // Использовать значение, только если условие истинно ?.let { // Делаем что-то, только если значение не равно null println("Мы исправили это: $it") } //конец выборки } // Функция расширения fun Int.ordinal() = this.absoluteValue.let { iAbs -> суффикс val = if (iAbs % 100 в 11..13) "th" else когда (iAbs % 10) { 1 -> "ст" 2 -> «й» 3 -> "й" иначе -> "й" } "$этот$суффикс" } Окно класса данных (ширина переменной: Int, высота переменной: Int, переменная isVisible: логическое значение) весело createEmptyWindow() = Окно (0, 0, ложь) весело showWindow(окно: Окно) { println("Показано $окно") } Статус класса enum {OPEN, FIXED, IN_PROGRESS} Проблема класса данных (val status: Status) val issueById = mutableMapOf( "13456" для выдачи (Статус. ИСПРАВЛЕНО) )
импортировать kotlinx.coroutines.* импортировать kotlinx.coroutines.flow.* // начало выборки // Более 50% профессиональных разработчиков используют сопрограммы // сообщаем о повышении производительности // (на основе внутренних данных Google) весело main () = runBlocking { val start = System.currentTimeMillis() coroutineScope { // Создаем область для сопрограмм val waitJob = launch { // Запуск сопрограммы ожидание(начало, 150) } countdownSignals(10, 300).collect { значение -> // Сбор элементов потока log(начало, "Обратный отсчет: $значение") } waitJob.cancel() // Отмена сопрограммы } log(start, "Liftoff!") // Выполнение продолжается, когда все } // сопрограммы завершили работу //конец выборки fun countdownSignals(n: Int, delayMillis: Long): Flow= поток { // Построитель потока for (i in (1. .n).reversed()) { delay(delayMillis) // Задержка в выдаче сигналов emit(i) // Выдать элемент потока } } // Функция, которую можно приостановить и возобновить позже приостановить ожидание удовольствия (начало: долго, delayMillis: долго) { while (currentCoroutineContext().isActive) { // Проверяем контекст сопрограммы log(начало, "Ожидание...") delay(delayMillis) // Одновременное ожидание } } журнал развлечений (начало: длинное, сообщение: строка) { println("$msg после ${(System.currentTimeMillis() - start)/1000F}s") }
// Используйте любую существующую библиотеку или фреймворк JVM // Вызов кода Kotlin из Java без проблем @SpringBootApplication демонстрационное приложение класса весело main(аргументы: Array) { runApplication (*args) } @RestController класс MessageResource { @GetMapping забавный индекс(): Список<Сообщение> = listOf( Сообщение("1", "Привет!"), Сообщение("2", "Добрый день!"), Сообщение("3", "Привет!"), ) } Сообщение класса данных (действительный идентификатор: строка?, допустимый текст: строка)
Начать ↗
Делитесь кодом на своих условиях и для разных платформ
Упростите разработку кроссплатформенных проектов с помощью Kotlin Multiplatform. Это сокращает время, затрачиваемое на написание и сопровождение одного и того же кода для разных платформ, сохраняя при этом гибкость и преимущества нативного программирования.
Приложения Kotlin будут работать на разных операционных системах, таких как iOS, Android, macOS, Windows, Linux, watchOS и других.
Узнать о мультиплатформе Kotlin →
Узнать больше →
Большое, дружелюбное и полезное
сообщество
У Kotlin отличная поддержка и множество участников в быстрорастущем глобальном сообществе. Воспользуйтесь преимуществами богатой экосистемы с широким спектром библиотек сообщества. Помощь всегда рядом — обратитесь к многочисленным ресурсам сообщества или напрямую обратитесь к команде Kotlin.
Присоединяйтесь к сообществу →
Gradle представляет Kotlin как язык для написания скриптов сборки
Corda — это платформа распределенного реестра с открытым исходным кодом, поддерживаемая крупными банками и полностью построенная на Kotlin
.
Evernote недавно интегрировала Kotlin в свой Android-клиент
Android-приложение Coursera частично написано на Kotlin
Spring использует языковые функции Kotlin, чтобы предлагать более лаконичные API
Весь новый код в Android-приложении Trello написан на языке Kotlin
Хотите попробовать?
Начало работы
Базовый синтаксис | Kotlin Documentation
Это набор основных элементов синтаксиса с примерами. В конце каждого раздела вы найдете ссылку на подробное описание соответствующей темы.
Вы также можете изучить все основы Kotlin с помощью бесплатного курса Kotlin Basics в Академии JetBrains.
Определение пакета и импорт
Спецификация пакета должна быть в начале исходного файла.
пакет my.demo
импортировать kotlin.text.*
// …
Не требуется совпадение каталогов и пакетов: исходные файлы могут располагаться в файловой системе произвольно.
См. пакеты.
Точка входа программы
Точкой входа приложения Kotlin является основная функция
.
весело main() {
println(«Привет, мир!»)
}
Другая форма main
принимает переменное количество аргументов String
.
весело main(args: Array
println(args.contentToString())
}
Вывести на стандартный вывод
напечатать
вывести свой аргумент на стандартный вывод.
весело main() {
// начало выборки
распечатать(«Здравствуйте»)
распечатать(«мир!»)
//конец выборки
}
println
выводит свои аргументы и добавляет разрыв строки, так что следующее печатаемое вами сообщение появляется на следующей строке.
весело main() {
// начало выборки
println(«Привет, мир!»)
распечатать(42)
//конец выборки
}
Функции
Функция с двумя Параметры Int
и тип возвращаемого значения Int
.
// начало выборки
забавная сумма (a: Int, b: Int): Int {
вернуть а + б
}
//конец выборки
веселая главная () {
print(«Сумма 3 и 5 равна»)
println (сумма (3, 5))
}
Тело функции может быть выражением. Его возвращаемый тип выводится.
// начало выборки
забавная сумма (a: Int, b: Int) = a + b
//конец выборки
веселая главная () {
println(«Сумма 19 и 23 равна ${сумма(19, 23)}»)
}
Функция, которая не возвращает значимого значения.
// начало выборки
fun printSum(a: Int, b: Int): Unit {
println(«Сумма $a и $b равна ${a + b}»)
}
//конец выборки
веселая главная () {
printSum(-1, 8)
}
Тип возвращаемого значения Unit
может быть опущен.
// начало выборки
fun printSum(a: Int, b: Int) {
println(«Сумма $a и $b равна ${a + b}»)
}
//конец выборки
веселая главная () {
printSum(-1, 8)
}
См. Функции.
Переменные
Локальные переменные только для чтения определяются с помощью ключевого слова val
. Им можно присвоить значение только один раз.
весело main() {
// начало выборки
val a: Int = 1 // немедленное присвоение
val b = 2 // выводится тип `Int`
val c: Int // Требуется тип, если инициализатор не указан
c = 3 // отложенное присваивание
//конец выборки
println(«а = $а, б = $b, с = $с»)
}
Переменные, которые можно переназначать, используют ключевое слово var
.
весело main() {
// начало выборки
var x = 5 // выводится тип `Int`
х += 1
//конец выборки
println(«х = $х»)
}
Вы можете объявлять переменные на верхнем уровне.
//начало выборки
знач PI = 3,14
переменная х = 0
весело приращениеX () {
х += 1
}
//конец выборки
веселая главная () {
println(«x = $x; PI = $PI»)
приращениеX()
println(«приращениеX()»)
println(«x = $x; PI = $PI»)
}
См. также Свойства.
Создание классов и экземпляров
Чтобы определить класс, используйте ключевое слово class
.
class Shape
Свойства класса могут быть перечислены в его объявлении или теле.
класс Прямоугольник (высота переменной: Double, длина переменной: Double) {
var периметр = (высота + длина) * 2
}
Конструктор по умолчанию с параметрами, указанными в объявлении класса, доступен автоматически.
класс Прямоугольник (высота переменной: Double, длина переменной: Double) {
var периметр = (высота + длина) * 2
}
веселая главная () {
// начало выборки
val прямоугольник = прямоугольник (5.0, 2.0)
println(«Периметр ${rectangle.perimeter}»)
//конец выборки
}
Наследование между классами объявляется двоеточием ( :
). Классы являются окончательными по умолчанию; чтобы сделать класс наследуемым, пометьте его как открыть
.
открытый класс Форма
класс Rectangle (высота var: Double, длина var: Double): Shape () {
var периметр = (высота + длина) * 2
}
См. классы, объекты и экземпляры.
Как и большинство современных языков, Kotlin поддерживает однострочные (или end-of-line ) и многострочные ( block ) комментарии.
// Это комментарий в конце строки
/* Это блочный комментарий
на несколько строк. */
Блочные комментарии в Kotlin могут быть вложенными.
/* Здесь начинается комментарий
/* содержит вложенный комментарий */
и заканчивается здесь. */
См. Документирование кода Kotlin для получения информации о синтаксисе комментариев к документации.
Строковые шаблоны
fun main() {
// начало выборки
вар а = 1
// простое имя в шаблоне:
val s1 = «а есть $а»
а = 2
// произвольное выражение в шаблоне:
val s2 = «${s1.replace(«is», «was»)}, но теперь это $a»
//конец выборки
println(s2)
}
Дополнительные сведения см. в разделе Строковые шаблоны.
Условные выражения
//sampleStart
удовольствие maxOf(a: Int, b: Int): Int {
если (а > б) {
вернуть
} еще {
вернуть б
}
}
//конец выборки
веселая главная () {
println(«максимум 0 и 42 равно ${maxOf(0, 42)}»)
}
В Kotlin if
также можно использовать как выражение.
// начало выборки
fun maxOf(a: Int, b: Int) = if (a > b) a else b
//конец выборки
веселая главная () {
println(«максимум 0 и 42 равно ${maxOf(0, 42)}»)
}
См. , если
-выражения.
for loop
fun main() {
// начало выборки
val items = listOf(«яблоко», «банан», «киви»)
для (пункт в пунктах) {
println(элемент)
}
//конец выборки
}
или
fun main() {
// начало выборки
val items = listOf(«яблоко», «банан», «киви»)
for (индекс в items.indices) {
println(«элемент $index равен ${items[index]}»)
}
//конец выборки
}
См. Цикл.
цикл while
весело main() { См. цикл while. //sampleStart Посмотреть, когда выражение. Проверить, находится ли число в диапазоне, используя оператор весело main() { Проверить, не выходит ли число за допустимые пределы. весело main() { если (-1 !in 0..list.lastIndex) { Повторить диапазон. весело main() { Или в последовательности. весело main() { См. Диапазоны и последовательности. Перебор коллекции. весело main() { Проверить, содержит ли коллекция объект, используя оператор весело main() { Использование лямбда-выражений для фильтрации и сопоставления коллекций: fun main() { См. Обзор коллекций. Ссылка должна быть явно помечена как допускающая значение NULL, если возможно Вернуть fun parseInt(str: String): Int? { Использовать функцию, возвращающую нулевое значение: fun parseInt(str: String): Int? { или fun parseInt(str: String): Int? { // начало выборки См. Null-безопасность. Оператор //sampleStart или // начало выборки или даже //начало выборки
// начало выборки
val items = listOf(«яблоко», «банан», «киви»)
переменный индекс = 0
в то время как (индекс когда выражение
забавное описание (obj: Any): String =
когда (объект) {
1 -> «Один»
«Здравствуйте» -> «Приветствие»
длинный -> «длинный»
!is String -> «Не строка»
еще -> «Неизвестно»
}
//конец выборки
веселая главная () {
println(описать(1))
println(описать(«Привет»))
println(описать(1000L))
println(описать(2))
println(описать(«другое»))
} Диапазоны
в
.
// начало выборки
значение х = 10
значение у = 9
если (х в 1..у+1) {
println(«входит в диапазон»)
}
//конец выборки
}
// начало выборки
val list = listOf («а», «б», «в»)
println(«-1 вне допустимого диапазона»)
}
если (list.size ! в list.indices) {
println(«Размер списка также выходит за допустимый диапазон индексов списка»)
}
//конец выборки
}
// начало выборки
для (х в 1..5) {
печать (х)
}
//конец выборки
}
// начало выборки
для (x в 1..10 шаге 2) {
печать (х)
}
println()
for (x in 9 downTo 0 step 3) {
печать (х)
}
//конец выборки
} Коллекции
val items = listOf(«яблоко», «банан», «киви»)
// начало выборки
для (пункт в пунктах) {
println(элемент)
}
//конец выборки
} в
.
val items = setOf(«яблоко», «банан», «киви»)
// начало выборки
когда {
«оранжевый» в пунктах -> println («сочный»)
«яблоко» в пунктах -> println («яблоко тоже подойдет»)
}
//конец выборки
}
// начало выборки
val fruit = listOf(«банан», «авокадо», «яблоко», «киви»)
фрукты
.filter { it.startsWith («а») }
.sortedBy {это}
.map { it.uppercase() }
.forEach {println(это)}
//конец выборки
} Значения, допускающие значение NULL, и проверки на значение NULL
значение null
. Имена типов, допускающие значение NULL, имеют ?
в конце. null
, если str
не содержит целое число:
// …
}
вернуть str.toIntOrNull()
}
// начало выборки
fun printProduct(arg1: строка, arg2: строка) {
val x = parseInt (arg1)
val y = parseInt (arg2)
// Использование `x * y` приводит к ошибке, поскольку они могут содержать нули.
если (х != null && y != null) {
// x и y автоматически приводятся к ненулевым значениям после нулевой проверки
println(х * у)
}
еще {
println(«‘$arg1’ или ‘$arg2’ не является числом»)
}
}
//конец выборки
веселая главная () {
печататьПродукт(«6», «7»)
printProduct(«а», «7»)
printProduct(«а», «б»)
}
вернуть str.toIntOrNull()
}
fun printProduct(arg1: строка, arg2: строка) {
val x = parseInt (arg1)
val y = parseInt (arg2)
// . ..
если (х == ноль) {
println(«Неверный числовой формат в arg1: ‘$arg1′»)
возвращаться
}
если (у == ноль) {
println(«Неверный числовой формат в arg2: ‘$arg2′»)
возвращаться
}
// x и y автоматически приводятся к ненулевым значениям после нулевой проверки
println(х * у)
//конец выборки
}
веселая главная () {
печататьПродукт(«6», «7»)
printProduct(«а», «7»)
printProduct(«99», «б»)
} Проверка типов и автоматическое приведение типов
is
проверяет, является ли выражение экземпляром типа. Если неизменяемая локальная переменная или свойство проверяется для определенного типа, нет необходимости приводить ее явно:
fun getStringLength(obj: Any): Int? {
если (объект является строкой) {
// `obj` автоматически приводится к `String` в этой ветке
вернуть obj.length
}
// `obj` по-прежнему имеет тип `Any` за пределами ветки с проверкой типов
вернуть ноль
}
//конец выборки
веселая главная () {
весело printLength(объект: любой) {
println(«Получение длины ‘$obj’. Результат: ${getStringLength(obj) ?: «Ошибка: объект не является строкой»} «)
}
printLength(«Непонятности»)
длина печати(1000)
длина печати (список (любой ()))
}
fun getStringLength(obj: Any): Int? {
if (obj !is String) возвращает null
// `obj` автоматически приводится к `String` в этой ветке
вернуть obj.length
}
//конец выборки
веселая главная () {
весело printLength(объект: любой) {
println(«Получение длины ‘$obj’. Результат: ${getStringLength(obj) ?: «Ошибка: объект не является строкой»} «)
}
printLength(«Непонятности»)
длина печати(1000)
длина печати (список (любой ()))
}
fun getStringLength(obj: Any): Int? {
// `obj` автоматически преобразуется в `String` справа от `&&`
если (obj является строкой && obj.length > 0) {
вернуть obj.length
}
вернуть ноль
}
//конец выборки
веселая главная () {
весело printLength(объект: любой) {
println(«Получение длины ‘$obj’.