Сообщения

Сообщения за 2020

Возврат и прыжки в Kotlin

Изображение
Возврат и прыжки В Kotlin есть три выражения структурного скачка: return. По умолчанию возвращается из ближайшей включающей функции или анонимной функции. break. Завершает ближайший охватывающий цикл. continue. Переходит к следующему шагу ближайшего охватывающего цикла. Все эти выражения можно использовать как часть более крупных выражений: val s = person.name ?: return Тип этих выражений - тип Nothing. Break и Continue метки Любое выражение в Kotlin может быть помечено меткой. Метки имеют форму идентификатора, за которым следует знак @, например: abc@, 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 переходит к следующе

For циклы в Kotlin

Изображение
Цикл for перебирает все, что предоставляет итератор. Это эквивалентно циклу foreach в таких языках, как C#. Синтаксис следующий: for (item in collection) print(item) Тело может быть блоком. for (item: Int in ints) { // ... } Как упоминалось выше, for выполняет итерацию всего, что предоставляет итератор, т.е. имеет функцию-член или функцию расширения iterator(), возвращаемый тип которого имеет функцию-член или функцию расширения next(), и имеет функцию-член или функцию расширения hasNext(), которая возвращает Boolean. Все эти три функции необходимо пометить как operator. Чтобы перебрать диапазон чисел, используйте выражение диапазона: for (i in 1..3) { println(i) } for (i in 6 downTo 0 step 2) { println(i) } Цикл for по диапазону или массиву компилируется в цикл на основе индекса, который не создает объект-итератор. Если вы хотите перебрать массив или список с индексом, вы можете сделать это следующим образом: for (i in array.indices) {

Выражение when в Kotlin

Изображение
Выражение when заменяет оператор switch в C-подобных языках. В простейшем виде это выглядит так when (x) { 1 -> print("x == 1") 2 -> print("x == 2") else -> { // Обратите внимание на блок print("x не равно 1 и не равно 2") } } when сопоставляет свой аргумент со всеми ветвями последовательно, пока не будет выполнено какое-либо условие ветвления. when может использоваться как выражение или как утверждение. Если оно используется как выражение, значение удовлетворенной ветви становится значением всего выражения. Если он используется как утверждение, значения отдельных ветвей игнорируются. (Как и в случае с if, каждая ветвь может быть блоком, а ее значением является значение последнего выражения в блоке.) Ветвь else оценивается, если ни одно из других условий ветвления не удовлетворяется. Если when используется в качестве выражения, ветвь else является обязательной, если компилятор не может доказать, что все возможные сл

Выражение if в Kotlin

Изображение
В Kotlin if - это выражение, то есть возвращает значение. Следовательно, нет тернарного оператора (condition ? then : else), потому что обычный if отлично работает в этой роли. // Традиционное использование var max = a if (a < b) max = b // С ветвью else var max: Int if (a > b) { max = a } else { max = b } // Как выражение val max = if (a > b) a else b if ветви могут быть блоками, а последнее выражение - это значение блока: val max = if (a > b) { print("Выбрать a") a } else { print("Выбрать b") b } Если вы используете if как выражение, а не как оператор (например, возвращаете его значение или присваиваете его переменной), выражение должно иметь ветвь else. Читайте также: Массивы в Kotlin Строки в Kotlin Пакеты и импорты в Kotlin

Пакеты и импорты в Kotlin

Изображение
Исходный файл может начинаться с объявления пакета: package org.example fun printMessage() { /*...*/ } class Message { /*...*/ } // ... Все содержимое (например, классы и функции) исходного файла содержатся в объявленном пакете. Итак, в приведенном выше примере полное имя printMessage() - org.example.printMessage, а полное имя Message - org.example.Message. Если пакет не указан, содержимое такого файла принадлежит пакету по умолчанию, который не имеет имени. Импорты по умолчанию Ряд пакетов импортируется в каждый файл Kotlin по умолчанию: kotlin.* kotlin.annotation.* kotlin.collections.* kotlin.comparisons.* (since 1.1) kotlin.io.* kotlin.ranges.* kotlin.sequences.* kotlin.text.* Дополнительные пакеты импортируются в зависимости от целевой платформы: JVM: java.lang.* kotlin.jvm.* JS: kotlin.js.* Импорты Помимо импорта по умолчанию, каждый файл может содержать свои собственные директивы импорта. Мы можем импортировать одно имя, например, impo

Строки в Kotlin

Изображение
Строки представлены типом String . Строки неизменны. Элементы строки - это символы, к которым можно обратиться с помощью операции индексации: s[i]. Строка может быть повторена с помощью цикла for: for (c in str) { println(c) } Вы можете объединять строки, используя оператор +. Это также работает для объединения строк со значениями других типов, если первый элемент в выражении является строкой: val s = "abc" + 1 println(s + "def") Обратите внимание, что в большинстве случаев использование строковых шаблонов или необработанных строк предпочтительнее конкатенации строк. Строковые литералы В Kotlin есть два типа строковых литералов: экранированные строки, в которых могут быть экранированные символы, и необработанные строки, которые могут содержать символы новой строки и произвольный текст. Вот пример экранированной строки: val s = "Hello, world!\n" Экранирование выполняется обычным способом с обратной косой чертой. Необработанная с

Целые числа без знака в Kotlin

Изображение
Типы без знака доступны только с Kotlin 1.3 и в настоящее время являются экспериментальными. Kotlin вводит следующие типы для целых чисел без знака (unsigned integers): kotlin.UByte: 8-разрядное целое число без знака, от 0 до 255 kotlin.UShort: 16-разрядное целое число без знака, от 0 до 65535 kotlin.UInt: 32-разрядное целое число без знака, от 0 до 2^32 - 1 kotlin.ULong: 64-разрядное целое число без знака, от 0 до 2^64 - 1 Типы без знака поддерживают большинство операций их аналогов со знаком. Обратите внимание, что изменение типа с типа без знака на аналог со знаком (и наоборот) является двоичным несовместимым изменением. Типы без знака реализованы с использованием другой экспериментальной функции, а именно встроенных классов (inline classes). Специализированные классы Так же, как и для примитивов, каждый тип без знака имеет соответствующий тип, представляющий массив, специализированный для этого типа без знака: kotlin.UByteArray: массив байтов без знака kotlin.UShortA

Массивы в Kotlin

Изображение
Массивы в Kotlin представлены классом Array, который имеет функции get и set (которые превращаются в [] в соответствии с соглашениями о перегрузке операторов) и свойство size вместе с несколькими другими полезными функциями-членами: class Array<T> private constructor() { val size: Int operator fun get(index: Int): T operator fun set(index: Int, value: T): Unit operator fun iterator(): Iterator<T> // ... } Чтобы создать массив, мы можем использовать библиотечную функцию arrayOf() и передать ей значения элементов, так что arrayOf(1, 2, 3) создаст массив [1, 2, 3]. Кроме того, библиотечная функция arrayOfNulls() может использоваться для создания массива заданного размера, заполненного null элементами. Другой вариант - использовать конструктор Array, который принимает размер массива, и функцию, которая может возвращать начальное значение каждого элемента массива с учетом его индекса: // Создает Array<String> со значениями ["0", &

Булев тип в Kotlin

Изображение
Тип Boolean представляет логическое значение и имеет два значения: true и false. Булевы значения упаковываются, если требуется nullable ссылка. Встроенные операции над логическими значениями включают || - ленивое ИЛИ && - ленивое И ! - отрицание Читайте также: Операции с числовыми типами в Kotlin Литеральные константы чисел в Kotlin Числовые типы в Kotlin: представление, явные преобразования

Символы в Kotlin

Изображение
Символы в Kotlin представлены типом Char . Их нельзя трактовать напрямую как числа fun check(c: Char) { if (c == 1) { // ОШИБКА: несовместимые типы // ... } } Символьные литералы идут в одинарных кавычках: '1'. Специальные символы могут быть экранированы с помощью обратной косой черты. Поддерживаются следующие escape-последовательности: \t, \b, \n, \r, \', \", \\ и \$. Чтобы кодировать любой другой символ, используйте синтаксис escape-последовательности Unicode: '\uFF00'. Мы можем явно преобразовать символ в Int число: fun decimalDigitValue(c: Char): Int { if (c !in '0'..'9') throw IllegalArgumentException("Out of range") return c.toInt() - '0'.toInt() // Явные преобразования в числа } Как и числа, символы помещаются в контейнер, когда требуется обнуляемая ссылка. Идентичность не сохраняется в результате операции помещения в контейнер. Читайте также: Операции с числовыми типам

Сравнение чисел с плавающей точкой в Kotlin

Изображение
Операции над числами с плавающей запятой, обсуждаемые в этом посте: Проверка на равенство: a == b и a != b Операторы сравнения: a < b, a > b, a <= b, a >= b Создание экземпляра диапазона и проверка диапазона: a..b, x in a..b, x !in a..b Когда операнды a и b статически известны как Float или Double или их обнуляемые аналоги (тип объявляется или выводится или является результатом умного приведения), операции над числами и диапазоном, который они формируют, соответствуют IEEE 754 стандарту для арифметики с плавающей точкой. Однако для поддержки общих вариантов использования и обеспечения общего упорядочения, когда операнды не статически типизированы как числа с плавающей запятой (например, Any, Comparable<...>, параметр типа), в операциях используются реализации equals и compareTo для Float и Double, который не соответствует стандарту, так что: NaN считается равным себе NaN считается больше, чем любой другой элемент, включая POSITIVE_INFINITY -0.0 считается ме

Операции с числовыми типами в Kotlin

Изображение
Kotlin поддерживает стандартный набор арифметических операций над числами (+ - * / %), которые объявлены как члены соответствующих классов (но компилятор оптимизирует вызовы до соответствующих инструкций). Деление целых чисел Обратите внимание, что деление между целыми числами всегда возвращает целое число. Любая дробная часть отбрасывается. Например: val x = 5 / 2 //println(x == 2.5) // ERROR: Operator '==' cannot be applied to 'Int' and 'Double' println(x == 2) Это верно для деления между любыми двумя целочисленными типами. val x = 5L / 2 println(x == 2L) Чтобы вернуть тип с плавающей точкой, явно преобразуйте один из аргументов в тип с плавающей точкой. val x = 5 / 2.toDouble() println(x == 2.5) Побитовые операции Что касается побитовых операций, то для них нет специальных символов, а только именованные функции, которые можно вызывать в инфиксной форме, например: val x = (1 shl 2) and 0x000FF000 Вот полный список побитовых опера

Числовые типы в Kotlin: представление, явные преобразования

Изображение
Представление На платформе Java числа физически хранятся в виде примитивных типов JVM, если только нам не нужна ссылка на обнуляемое число (например, Int?) Или не используются дженерики. В последних случаях числа имеют обертку. Обратите внимание, что обертывание чисел не обязательно сохраняет идентичность: val a: Int = 10000 println(a === a) // Печатает 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a println(boxedA === anotherBoxedA) // !!!Печатает 'false'!!! С другой стороны, это сохраняет равенство: val a: Int = 10000 println(a == a) // Печатает 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a println(boxedA == anotherBoxedA) // Печатает 'true' Явные преобразования Из-за разных представлений меньшие типы не являются подтипами больших. Если бы они были, у нас были бы проблемы следующего вида: // Гипотетический код, на самом деле не компилируется: val a: Int? = 1 // обернутый Int (java.lang.Integer) val b: Long? = a /

Литеральные константы чисел в Kotlin

Изображение
Существуют следующие виды литеральных констант для целочисленных значений: Десятичные: 123 Long обозначены заглавными буквами L: 123L Шестнадцатеричные: 0x0F Двоичные: 0b00001011 ПРИМЕЧАНИЕ. Восьмеричные литералы не поддерживаются. Kotlin также поддерживает обычные обозначения для чисел с плавающей точкой: По умолчанию Double: 123.5, 123.5e10 Float помечены f или F: 123.5f Подчеркивания в числовых литералах (с версии 1.1) Вы можете использовать подчеркивания, чтобы сделать числовые константы более читабельными: val oneMillion = 1_000_000 val creditCardNumber = 1234_5678_9012_3456L val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010 Читайте также: Числовые типы в Kotlin

Числовые типы в Kotlin

Изображение
В Kotlin все является объектом в том смысле, что мы можем вызывать функции-члены и свойства для любой переменной. Некоторые из типов могут иметь специальное внутреннее представление - например, числа, символы и логические значения могут быть представлены как примитивные значения во время выполнения - но для пользователя они выглядят как обычные классы. Kotlin предоставляет набор встроенных типов, которые представляют числа. Для целых чисел существует четыре типа с разными размерами и, следовательно, диапазонами значений. Тип Размер (битов) Минимальное значение Максимальное значение Byte 8 -128 127 Short 16 -32768 32767 Int 32 -2,147,483,648 (-2 exp 31) 2,147,483,647 ((2 exp 31) - 1) Long 64 -9,223,372,036,854,775,808 (-2 exp 63) 9,223,372,036,854,775,807 ((2 exp 63) - 1) Все переменные, инициализированные целочисленными значениями, не превышающими максимальное значение Int, имеют предполагаемый тип Int. Если начальное значение превышает это значение,