String to Long в Kotlin: 5 фатальных ошибок и как их избежать

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Как конвертировать String в Long в Kotlin и не сойти с ума: разбор типичных ошибок

Каждый разработчик на Kotlin рано или поздно сталкивается с задачей: нужно взять строку, которую ввёл пользователь, пришёл ответ от API или прочитался файл, и превратить её в число типа Long. Казалось бы, что может быть проще? Но именно здесь, на ровном месте, новички (да и опытные программисты) совершают ошибки, которые приводят к падениям приложения, пустым экранам и бессонным ночам дебага.

В этой статье мы разберём пять самых частых ошибок при конвертации String в Long в Kotlin. Вы узнаете не только как их исправить, но и как писать код, который не сломается при первом же невалидном вводе. Поехали!

Ошибка №1: Наивное использование toLong() без обработки исключений

Самый прямолинейный способ — вызвать метод toLong() у строки. Да, это работает, но только если строка содержит корректное число. В противном случае — привет, NumberFormatException!

val userInput = "123abc"
val number: Long = userInput.toLong() // Вылетит NumberFormatException!

Почему это плохо? Исключение в рантайме — это всегда риск. Если ваше приложение не обработает его, пользователь увидит краш.

Как исправить? Используйте try-catch или, что ещё лучше, безопасную альтернативу — toLongOrNull().

val userInput = "123abc"
val number: Long? = userInput.toLongOrNull() // Вернёт null, никакого исключения
println(number) // null

Метод toLongOrNull() — ваш спаситель. Если строку нельзя преобразовать, он просто вернёт null, и вы спокойно обработаете этот случай.

Ошибка №2: Игнорирование null и пустых строк

В Kotlin типы явно делятся на nullable и non-null. Если вы попытаетесь вызвать toLong() у строки, которая может быть null, компилятор вас не пропустит. Но есть подвох: пустая строка ("") — это не null, и она тоже вызовет исключение.

val nullableString: String? = null
// nullableString.toLong() // Ошибка компиляции: только safe (?.) или non-null asserted (!!.) вызовы

val emptyString = ""
emptyString.toLongOrNull() // null, всё хорошо

Практический совет: Всегда проверяйте строку на пустоту или используйте toLongOrNull() в паре с элвис-оператором ?:.

fun parseUserAge(input: String?): Long {
    return input?.toLongOrNull() ?: 0L // Если null или не число — вернём 0
}

Такой подход делает код идиоматичным и безопасным.

Ошибка №3: Забываем про пробелы и невидимые символы

Пользователи — существа непредсказуемые. Они могут случайно поставить пробел перед числом или в конце. Строка из файла может содержать символы перевода строки \n. Метод toLongOrNull() не умеет обрезать строку — он ожидает, что строка состоит только из цифр (и, возможно, знака минус).

val dirtyString = "  42  "
dirtyString.toLongOrNull() // null, потому что есть пробелы

Решение: Всегда вызывайте trim() перед конвертацией.

val cleanString = dirtyString.trim()
val number: Long? = cleanString.toLongOrNull()
println(number) // 42

Это один из самых простых и эффективных способов избежать багов. Запомните правило: trim before you convert.

Ошибка №4: Проблемы с локализацией и разделителями

В разных странах числа записывают по-разному. В США и России для разделения тысяч используют запятую (1,234) или пробел (1 234), а десятичные дроби отделяют точкой. В Европе всё наоборот: запятая — это десятичный разделитель. Kotlin по умолчанию ожидает «чистый» числовой формат без разделителей.

val usNumber = "1,234"
usNumber.toLongOrNull() // null — запятая недопустима

val germanNumber = "1.234"
germanNumber.toLongOrNull() // null — точка воспринимается как десятичный разделитель, но дробная часть не указана

Как быть? Если вы работаете с пользовательским вводом или данными из разных источников, предварительно очистите строку от всех нечисловых символов, кроме знака минус.

fun cleanAndParse(input: String): Long? {
    val cleaned = input.replace(Regex("[^\\d-]"), "") // Удаляем всё, кроме цифр и минуса
    return cleaned.toLongOrNull()
}

println(cleanAndParse("1,234"))  // 1234
println(cleanAndParse("1 234"))  // 1234
println(cleanAndParse("1.234"))  // 1234 (если это не дробное число)

Важно: этот метод подходит только для целых чисел. Если вы ожидаете дробные числа, логика будет сложнее.

Ошибка №5: Игнорирование переполнения (overflow)

Диапазон типа Long в Kotlin — от -9 223 372 036 854 775 808 до 9 223 372 036 854 775 807. Если строка содержит число за пределами этого диапазона, toLong() или toLongOrNull() выбросят NumberFormatException (или вернут null).

val hugeNumber = "99999999999999999999999"
println(hugeNumber.toLongOrNull()) // null — переполнение

Что делать? Если вы ожидаете потенциально большие числа, рассмотрите использование BigInteger из Java или библиотек, которые поддерживают произвольную точность. Или, как минимум, проверяйте длину строки перед конвертацией.

fun safeParseLong(input: String): Long? {
    val trimmed = input.trim()
    if (trimmed.length > 19) return null // Максимум 19 цифр для Long (с учётом минуса)
    return trimmed.toLongOrNull()
}

Это не панацея, но хорошая защита от наивных ошибок.

Итоговый чек-лист: как правильно конвертировать String в Long в Kotlin

Давайте соберём все рекомендации в один универсальный подход. Вот функция, которая учитывает все пять ошибок:

fun parseStringToLong(input: String?): Long? {
    if (input == null) return null
    val cleaned = input.trim().replace(Regex("[^\\d-]"), "")
    if (cleaned.isEmpty() || cleaned == "-") return null
    return cleaned.toLongOrNull()
}

// Примеры использования                

Блоги

Рекомендаций по книгам