1. Зачем нужна конвертация типов?
Kotlin — это строго (статически) типизированный язык. Если у компьютера есть “коробочка” для числа, то попытка засунуть туда текст — примерно то же самое, что и попытка вставить вилку в USB-разъём. Компилятор вам такое не простит! 😡
Однако, в жизни мы часто работаем одновременно с разными типами данных. Например, у вас есть строка, которая содержит число. Вот тут-то и нужна конвертация (или преобразование) типов.
Рассмотрим пример. Допустим, вы хотите хранить количество пользователей:
val a: Int = 1
val b: Int = "2"
val c: Int = "три"
Компилятор тут сразу скажет: “Ты меня за кого держишь? Я не умею автоматически преобразовывать строку в число, без тебя никак. Нужно привести строку к числу явно".
В Kotlin есть несколько путей конвертации, и каждый — со своими плюсами, минусами и типичными граблями.
2. Преобразовываем Int в String
В нашей работе часто требуется получить строковое представление числа: например, чтобы вывести его на экран, сохранить в файл, передать по сети, объединить с текстом и т.д. В Kotlin для этого существует сразу несколько способов, каждый из которых удобен в разных ситуациях.
Функция toString()
Это основной и самый распространённый способ:
val number = 42
val str = number.toString() // str == "42"
toString() преобразует значение в такую строку, которая соответствует типу этого значения.
Конкатенация с пустой строкой
Старый, но рабочий способ:
val number = 42
val str = "" + number
Такой подход быстро работает для простых случаев, но менее явен для читающего код программиста.
3. Неявное преобразование в строку
Как уже говорилось выше, разработчики Kotlin сделали так, что абсолютно все переменные, объекты, выражения в Kotlin можно преобразовать к типу String.
Более того, это автоматически происходит, когда мы складываем тип String с каким-нибудь другим типом. Примеры:
val a = 5
val name = "Аня" + a // name содержит строку Аня5
val a = 5
val city = a + "New York" + a // city содержит строку 5New York5
val number = 10
val code = "Yo"
val message = "Hello! " + number + code // message содержит строку Hello! 10Yo
Во всех трёх примерах мы спокойно складывали переменные типа Int и String, и в результате всегда получался тип String.
Примеры:
val a = 5
val name = "1" + a // name содержит строку 15
val a = 5
val city = a + "9" + a // city содержит строку 595
val number = 10
val code = "10"
val message = "" + number + code // message содержит строку 1010
Операция сложения выполняется слева направо, так что результат может быть несколько неожиданным. Пример:
val a = 5
val name = a + a + "1" + a // name содержит строку 1015
Порядок выполнения: ((a + a) + "1") + a
4. Преобразование строки в число: toInt()
Чтобы преобразовать число в строку в Kotlin, достаточно сложить его и пустую строку:
val str = "" + число
А что делать, если нужно преобразовать строку в число? Ну, любую строку в число преобразовать нельзя. Но если строка состоит только из цифр, то всё-таки можно. Для этого в Kotlin есть специальная функция.
Выглядит эта команда так:
val x: Int = строка.toInt()
Где val x: Int — это объявление целочисленной переменной x, а строка — это число, заданное в виде строки (строка, состоящая из цифр).
Примеры:
val str = "123"
val number1 = str.toInt() // number1 содержит число 123
val number2 = "321".toInt() // number2 содержит число 321
val number3 = ("321" + 0).toInt() // number3 содержит число 3210
val number4: Int = "321" // Не скомпилируется: переменная типа Int, а значение типа String
Для отрицательных значений это тоже работает: функция toInt() очень умная.
5. toIntOrNull(): безопасное преобразование в число
Когда строка приходит из внешнего мира (из файла или от пользователя), всегда есть риск, что она не число. И вот тут появляется более безопасный метод: toIntOrNull().
Он работает так: если строка действительно содержит целое число — вернёт Int. Если нет — вернёт null. И это принципиально другое поведение по сравнению с toInt(): вместо ошибки при запуске и падения программы мы получим особое значение — null.
null — это специальное значение, которое означает «значения нет». То есть null — это не 0, не пустая строка и не “ошибка текстом”. Это именно «отсутствие результата».
Расширяем тип Int: Int?
Тип Int хранит только валидные целые числа, он не может хранить строки, дробные числа, и null он тоже хранить не может. Поэтому в Kotlin есть расширенный вариант типа Int — Int?. Он хранит все значения типа Int и значение null (нет значения).
Это настолько распространённая ситуация, что в Kotlin это сделали частью языка: к любому типу в Kotlin можно добавить знак вопроса и получить "расширенный тип", который может хранить еще и null.
Если обычный Int всегда хранит число, то Int? читается как: «либо Int, либо null». Знак вопроса — это буквально пометка “может отсутствовать”.
Метод toIntOrNull() возвращает Int?, потому что он может и успешно распарсить число, и не распарсить.
Мини-пример: успешный и неуспешный разбор
Сейчас очень полезно увидеть, что произойдёт в обоих случаях, и не пытаться «угадать».
fun main() {
val ok: Int? = "15".toIntOrNull()
val bad: Int? = "15a".toIntOrNull()
println(ok) // 15
println(bad) // null
}
6. Шпаргалка и практика преобразований
Когда методов становится несколько, мозг просит «шпаргалку». Это нормально: вы не обязаны держать всё в голове — вы обязаны уметь быстро восстановить смысл.
Таблица-памятка: toString() vs toInt() vs toIntOrNull()
| Метод | Откуда → куда | Когда использовать | Что будет, если строка не число |
|---|---|---|---|
|
|
нужно вывести/склеить текст | не применимо (мы идём от числа) |
|
|
вы уверены, что строка корректна | ошибка при запуске (исключение) |
|
|
строка может быть «неаккуратной» | вернёт null |
Почему Kotlin заставляет быть явными
Когда люди впервые сталкиваются с явными преобразованиями, возникает желание: “А почему язык сам не догадается, что "123" — это число?” А язык как раз не хочет угадывать.
Представьте: вы написали "007". Это число семь? Или это код отдела? Или это строка, где важны ведущие нули? Если язык начнёт автоматически превращать строки в числа, он будет постоянно угадывать неправильно. Kotlin выбирает предсказуемость: если хочешь число — напиши toInt() или toIntOrNull() и возьми ответственность на себя.
И это, на самом деле, очень взрослая позиция языка. Kotlin как будто говорит: “Я не телепат. Я компилятор”.
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ