Освой Kotlin играючи
/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000
Определить тип числа
Узнать максимальное число из двух
Функции для типов
В Kotlin нет примитивных типов int, float, double и т.д., всё является объектами. Соответственно, вместо примитивных типов используются объекты Byte, Short, Int (не Integer как в Java), Double, Char, Float, Long, Boolean.
Float и Double являются числами с плавающей точкой и могут содержать 32 и 64 бита соответственно.
В Kotlin 1.3 появились беззнаковые типы: UByte (0...255), UShort (0...65535), UInt (0...2^32 - 1), ULong (0...2^64 - 1).
// You can define unsigned types using literal suffixes
val uint = 42u
val ulong = 42uL
val ubyte: UByte = 255u
// You can convert signed types to unsigned and vice versa via stdlib extensions:
val int = uint.toInt()
val byte = ubyte.toByte()
val ulong2 = byte.toULong()
// Unsigned types support similar operators:
val x = 20u + 22u
val y = 1u shl 8
val z = "128".toUByte()
val range = 1u..5u
Переменную типа Int нельзя присвоить переменной Long автоматически, нужно это сделать явно.
val x: Int = 20
val y: Long = x // нельзя
val y: Long = x.toLong()
Присвоить значение одного типа переменной другой типа можно при помощи специальных функций toByte(), toInt(), toLong(), toFloat(), toDouble(), toChar(), toShort(). Одну мы уже использовали выше.
val i: Int = 9
val d: Double = i.toDouble()
Переводим строку в число.
val stringNumber = "101"
val intValue = stringNumber.toInt()
val intValue = "101".toInt() // так тоже можно
Также принято указывать тип через литералы, это улучшает читаемость кода.
val i = 9 // Int
val iHex = 0x0f // Int в шестнадцатеричной записи
val l = 5L // Long
val d = 3.6 // Double
val f = 3.6F // Float
Можно представить число в двоичном коде, добавив префикс 0b. Для представления в шестнадцатеричной форме используется префикс 0x. Восьмеричная форма не поддерживается.
x = 0b10
y = 0xAB
В числах можно использовать символ подчёркивания для удобного чтения больших величин.
// миллион алых роз
println(1_000_000)
println(1_0) // число 10. вы вообще нормальный?
Тип Boolean может принимать два значения - true или false.
Сравнение этого типа аналогично как во многих языках.
&& // логическое AND
|| // логическое OR
! // логическое NOT
Сравнивать можно также через функции and(), or(), not(), xor(). А также можно сравнивать булевы типы между собой через compareTo(), при этом возвращаются числовые значения 0, 1, -1. При сравнении через equals() возвращаются булевы значения.
var t = true;
var f = false;
println("t.and(t): " + t.and(t)) // t.and(t): true
println("t.and(f): " + t.and(f)) // t.and(f): false
println("f.and(t): " + f.and(t)) // f.and(t): false
println("f.and(f): " + f.and(f)) // f.and(f): false
println("t.or(t): " + t.or(t)) // t.or(t): true
println("t.or(f): " + t.or(f)) // t.or(f): true
println("f.or(t): " + f.or(t)) // f.or(t): true
println("f.or(f): " + f.or(f)) // f.or(f): false
println("not(t): " + t.not()) // not(t): false
println("not(f): " + f.not()) // not(f): true
println("t.xor(t): " + t.xor(t)) // t.xor(t): false
println("t.xor(f): " + t.xor(f)) // t.xor(f): true
println("f.xor(t): " + f.xor(t)) // f.xor(t): true
println("f.xor(f): " + f.xor(f)) // f.xor(f): false
println("t.compareTo(t): " + t.compareTo(t)) // t.compareTo(t): 0
println("t.compareTo(f): " + t.compareTo(f)) // t.compareTo(f): 1
println("f.compareTo(t): " + f.compareTo(t)) // f.compareTo(t): -1
println("f.compareTo(f): " + f.compareTo(f)) // f.compareTo(f): 0
println("t.equals(t): " + t.equals(t)) // t.equals(t): true
println("t.equals(f): " + t.equals(f)) // t.equals(f): false
println("f.equals(t): " + f.equals(t)) // f.equals(t): false
println("f.equals(f): " + f.equals(f)) // f.equals(f): true
Перевести булево значение в строку можно через toString().
val isCat = true
println(isCat.toString())
Для символов используется класс Char. Символ обрамляется одиночными кавычками. Проверим, что это символ.
val letter: Char = 'c'
println("Current value of 'letter' is " + letter)
if (letter is Char) {
println("It is a character")
} else {
println("It is not character")
}
Если из контекста понятно, о каком типе идёт речь, то его можно опустить.
val letter = 'c' // понятно, что это Char
Тип Char нельзя использовать как число (как в Java), поэтому прибегаем к функции.
val c: Char = 'c'
val i: Int = c.toInt()
Аналогично используем toByte() и др. похожие функции.
Числовые символы можно конвертировать в число с помощью функции digitToInt() (Kotlin 1.5.2).
val charA = '9'
println(charA.digitToInt()) // 9
Функции проверки регистра символа и перевода в верхний или нижний регистр.
val hello = "Hello Kitty!"
for (c in hello) {
when {
// Устаревшие функции
//c.isLowerCase() -> print(c.toUpperCase())
//c.isUpperCase() -> print(c.toLowerCase())
// Kotlin 1.5.20
c.isLowerCase() -> print(c.uppercaseChar())
c.isUpperCase() -> print(c.lowercaseChar())
else -> print(c)
}
}
// hELLO kITTY!
Для проверки, является ли символ цифрой или буквой, используем Char.isDigit() и Char.isLetter().
Битовые операции происходят иначе. Если в Java используются специальные символы для сравнения: | для ИЛИ (OR) или & для И (AND), то в Kotlin не нужно запоминать, пишем словами.
val kotOR = FLAG1 or FLAG2
val kotAND = FLAG1 and FLAG2
Другие виды побитовых операторов: shl (signed shift left (Java <<)), shs (signed shift right (Java >>)), ushr (unsigned shift right (Java >>>)), xor, inv.
Узнать тип числа можно через конструкцию ::class.
println(9::class) // class kotlin.Int
println(9L::class) // class kotlin.Long
Функция maxOf() позволяет узнать максимальное число из двух предложенных вариантов.
print(maxOf(4, 5))
При сравнении объектов нужно добавить третий аргумент с компаратором.
val murzik = Cat("Murzik", 4, 5)
val barsik = Cat("Barsik", 8, 7)
// сравниваем котов по возрасту
print(maxOf(murzik, barsik, compareBy{it.age}))
Можно сравнивать не только два значения, но и три.
print(maxOf(8, 4, 2))
// сравниваем трёх котов по весу
val murzik = Cat("Murzik", 4, 9)
val barsik = Cat("Barsik", 8, 7)
var ryzhik = Cat("Ryzhik", 12, 11)
print(maxOf(murzik, barsik, ryzhik, compareBy{it.weight}))
У типов есть собственные функции. Например, можно узнать остаток после деления через функцию rem().
val number = 5
println(number.rem(3))
Также посмотрите на функции dec(), and() и другие.