Освой 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

Тип 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

Для символов используется класс 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() и другие.

Дополнительные материалы

Упражнения для простых типов

Реклама