Сообщения

Сообщения за ноябрь, 2018

Возвращение значения и переходы

В Kotlin имеется три выражения структурного перехода: return по умолчанию возвращается из ближайшей функции или анонимной функции. break завершает ближайщий цикл. continue переходи к следующему шагу ближайщего цикл. Все эти выражения могут использоваться как часть более крупных выражений: val s = person.name ?: return тип этих выражений является тип Nothing . Метки break и continue Либое выражение в Kotlin может быть отмечено меткой. Метки имееют форму идентификатора после которого следует символ @. Например bc@, fooBar@ являются валидными метками. Чтобы отметить меткой выражение мы просто помещаем метку перед его началом. loop@ for (i in 1..100) { // ... } Теперь мы можем определить break и continue меткой loop@ for (i in 1..100) { for (j in 1..100) { if (...) break@loop } } break с меткой переходит в точку выполнения находящейся сразу после цикла, отмеченного этой меткой. continue переходит к следующей итерации этого цикла. ...

Псевдонимы типов

Псевдонимы типов предоставляют альтернативные имена для существующих типов. Если имя типа слишком длинное, вы можете ввести другое более короткое имя и вместо него использовать новое. Это является полезным для сокращения длинные дженерик типов. Например, часто возникает соблазн уменьшить типы коллекций: typealias NodeSet = Set<Network.Node> typealias FileTable<K> = MutableMap<K, MutableList<File>> Вы можете предоставить различные псевдонимы для типов функций: typealias MyHandler = (Int, String, Any) -> Unit typealias Predicate<T> = (T) -> Boolean Вы может сделать новые имена для внутренних и вложенных классов: class A { inner class Inner } class B { inner class Inner } typealias AInner = A.Inner typealias BInner = B.Inner Псевдонимы типов не вводят новые типы. Они эквивалентны соответствующим базовым типам. Когда вы добавляете typealias Predicate <T> и используете Predicate <Int> в своем коде, компилятор Kotlin вс...

Вложенные и внутренние классы

Классы могут быть вложенными в другие классы: class Outer { private val bar: Int = 1 class Nested { fun foo() = 2 } } val demo = Outer.Nested().foo() // == 2 Внутренние классы Класс может быть помечен как inner , что дает возможность доступа к членам внешнего класса. Внутренние классы содержать ссылку на объект внешнего класса. class Outer { private val bar: Int = 1 inner class Inner { fun foo() = bar } } val demo = Outer().Inner().foo() // == 1 Анонимные внутренние классы Экземпляры анонимных внутренних классов создаются используя object выражение: window.addMouseListener(object: MouseAdapter() { override fun mouseClicked(e: MouseEvent) { ... } override fun mouseEntered(e: MouseEvent) { ... } }) Если объект является экземпляром функционального Java интерфейса, то есть у Java интерфейса один абстрактным метод, то вы можете создать объект используя лямбда выражение с префиксом в виде типа интрефейса: val listener = A...

Идиомы

Список выборочных и часто используемых идиом в языке Kotlin. Если у вас есть любимая идиома, вы можете внести ее сделав Pull Request. Создание DTOs (POJOs/POCOs) data class Customer(val name: String, val email: String) Слово data предоставляет для Customer класса следующею функциональность: getters (и setters в случаи var) для всех свойств equals() hashCode() toString() copy() component1() , component2() , …, для всех свойств Значения по умолчанию для параметров функции fun foo(a: Int = 0, b: String = "") { ... } Или по-другому, еще короче: val positives = list.filter { it > 0 } Интерполяция строк println("Name $name") Проверка экземпляра when (x) { is Foo -> ... is Bar -> ... else -> ... } Перемещение по map или по парам в list for ((k, v) in map) { println("$k -> $v") } k, v могут называться как угодно. Использование диапозонов for (i in 1..100) { ... } // ...

Enum классы

Наиболее простое использование enum клссов это реализациия type-safe enums: enum class Direction { NORTH, SOUTH, WEST, EAST } Каждый константа enum является объектом. Enum константы разделяются запятой.

Интерфейсы

Интерфейсы в Kotlin очень похожи на Java 8. Они могут содержать объявление абстрактных методов, а также реализации методов. Что отличает их от абстрактных классов, так это то, что интерфейсы не могут хранить состояние. У интерфейсов могут быть свойства, но они должны быть абстрактными или предоставлять реализацию аксессоров. Интерфейс в Kotlin языке определяется с использованием ключевого слова interface

Базовый синтаксис

Определение пакетов Спецификация пакета должна быть в верхней части исходного файла package my.demo import java.util.* // ... Не обязательно сопоставлять каталоги и пакеты: исходные файлы могут быть помещены произвольно в файловую систему. Смотрите подробнее о пакетах Определение функций Функция имеющая два параметра типа 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("sum of $a and $b is ${a + b}") } Тип возвращаемого значения может быть опущен: fun printSum(a: Int, b: Int) { println("sum of $a and $b is ${a + b}") } Определение переменных Локальная переменная assign-once (только чтение),присвоить значение можно один раз: val a: Int = 1 // присвоение значения val b = 2 // подразумевается ти...