Avatar ·

Как преобразовать строку (String) в число (Int) в Kotlin?

Всем привет! Я только начал изучать Kotlin и столкнулся с простой, но непонятной для меня задачей. У меня есть строка, полученная от пользователя через консольный ввод (readLine()), и я хочу использовать её как целое число для арифметических операций. Например, я пишу простой калькулятор, который складывает два числа: ```kotlin fun main() { print("Введите первое число: ") val firstInput = readLine() print("Введите второе число: ") val secondInput = readLine() val sum = firstInput + secondInput // Тут ошибка! println("Сумма: $sum") } ``` Конечно, этот код не работает, потому что firstInput и secondInput — это строки, и оператор + просто склеивает их, а не складывает. Я понимаю, что нужно как-то преобразовать строку в Int, но не знаю, как это сделать правильно. Пробовал писать что-то вроде `firstInput.toInt()`, но компилятор ругается на возможное исключение. Что делать, если пользователь введёт не число, а, например, "abc"? Как обработать такую ситуацию? Подскажите, пожалуйста, как в Kotlin правильно и безопасно преобразовывать строки в целые числа. Желательно с примерами кода и объяснением, как избежать краша программы при некорректном вводе. Заранее спасибо! <<>>

Безопасное преобразование строки в Int в Kotlin

В Kotlin есть несколько способов преобразовать строку в целое число. Самый простой — использовать функцию toInt(), но она может выбросить исключение NumberFormatException, если строка не является корректным числом. Поэтому для надёжного кода нужно использовать безопасные методы.

1. Базовое преобразование с обработкой исключений

Классический способ — обернуть вызов в try-catch:

fun main() {
    print("Введите число: ")
    val input = readLine()
    
    try {
        val number = input?.toInt() ?: 0
        println("Вы ввели: $number")
    } catch (e: NumberFormatException) {
        println("Ошибка: введённая строка не является числом")
    }
}

Здесь мы используем оператор ?. для безопасного вызова (если input — null) и элвис-оператор ?: для значения по умолчанию.

2. Безопасная функция toIntOrNull() (рекомендуемый способ)

В Kotlin есть встроенная функция toIntOrNull(), которая возвращает Int? (nullable Int). Если преобразование невозможно, она возвращает null вместо исключения:

fun main() {
    print("Введите число: ")
    val input = readLine()
    
    val number = input?.toIntOrNull()
    if (number != null) {
        println("Квадрат числа: ${number * number}")
    } else {
        println("Ошибка: введите корректное целое число")
    }
}

Это самый идиоматичный способ в Kotlin. Он лаконичен и безопасен.

3. Преобразование с проверкой регулярным выражением

Если нужно проверить формат строки перед преобразованием:

fun main() {
    print("Введите число: ")
    val input = readLine()
    
    if (input != null && input.matches(Regex("-?\\d+"))) {
        val number = input.toInt()
        println("Удвоенное значение: ${number * 2}")
    } else {
        println("Некорректный ввод")
    }
}

Регулярное выражение -?\\d+ означает: необязательный минус, затем одна или более цифр.

4. Обработка чисел с плавающей точкой

Если строка может содержать дробное число (например, "12.5"), сначала преобразуйте её в Double, а затем в Int:

fun main() {
    val input = "12.7"
    val doubleValue = input.toDoubleOrNull()
    val intValue = doubleValue?.toInt()  // отбрасывает дробную часть: 12
    
    println(intValue) // Выведет: 12
}

5. Преобразование для коллекций

Если у вас есть список строк, которые нужно преобразовать в числа:

fun main() {
    val strings = listOf("10", "20", "abc", "30")
    val numbers = strings.mapNotNull { it.toIntOrNull() }
    
    println(numbers) // [10, 20, 30] — "abc" отфильтровано
}

Итоговый пример для вашего калькулятора

fun main() {
    print("Введите первое число: ")
    val first = readLine()?.toIntOrNull()
    
    print("Введите второе число: ")
    val second = readLine()?.toIntOrNull()
    
    if (first != null && second != null) {
        val sum = first + second
        println("Сумма: $sum")
    } else {
        println("Ошибка: оба значения должны быть целыми числами")
    }
}

Важно: Всегда используйте toIntOrNull() или try-catch при работе с пользовательским вводом. Это защитит вашу программу от неожиданного завершения.

<<>>

Альтернативный подход: использование библиотеки для парсинга

Если вы работаете с большим объёмом данных или сложными форматами строк (например, числа с пробелами, знаками валюты, разделителями тысяч), встроенные методы могут не подойти. В таких случаях удобно использовать библиотеку Apache Commons Lang (через Java-совместимость) или написать свою функцию-расширение.

Пример функции-расширения для гибкого парсинга

fun String?.toIntSafe(default: Int = 0): Int {
    if (this == null) return default
    return try {
        // Удаляем пробелы и заменяем запятую на точку (для европейского формата)
        this.trim().replace(",", ".").toDouble().toInt()
    } catch (e: NumberFormatException) {
        default
    }
}

fun main() {
    println("1 234".toIntSafe())      // 1234
    println("12,5".toIntSafe())       // 12 (отбрасывает дробную часть)
    println("abc".toIntSafe(-1))      // -1 (значение по умолчанию)
    println(null.toIntSafe())         // 0
}

Использование Java-совместимости

Kotlin полностью совместим с Java, поэтому можно использовать Integer.parseInt() с try-catch:

import java.lang.Integer.parseInt

fun main() {
    val input = "42"
    try {
        val number = parseInt(input)
        println(number)
    } catch (e: NumberFormatException) {
        println("Не число")
    }
}

Однако этот способ менее идиоматичен для Kotlin, так как не использует nullable-типы и функции расширения. Рекомендую придерживаться toIntOrNull() как основного решения.