Kotlin - преобразование типов с исключениями переполнения - PullRequest
1 голос
/ 25 апреля 2019

(123L).toInt() производит 123, но Long.MAX_VALUE.toInt() производит -1.Очевидно, это не правильно.Без необходимости писать много шаблонного кода, есть ли способ заставить Kotlin выдавать исключение, когда значение выходит за пределы диапазона / границ для целевого типа?

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

TL; DR вы можете создать пользовательскую функцию расширения, которая проверяет, находится ли значение между Int.MIN_VALUE и Int.MAX_VALUE

fun Long.toIntThrowing() : Int {
    if (this < Int.MIN_VALUE || this > Int.MAX_VALUE) {
        throw RuntimeException()
    }

    return this.toInt()
}

Наблюдается "странное" поведение, которое вы наблюдаете, потому что в Kotlin, Long представляется как 64-битное целое число со знаком, а Int представляется как 32-битное целое число со знаком.

В то время как 123L легко представляется 32-битным целым числом, Long.MAX_VALUE переполняет Integer (почти) дважды, в результате чего вы наблюдаете поведение.

Я полагаю, что приведенный ниже пример лучше иллюстрирует это:

    println((2147483647L).toInt()) // the max 32 bit signed int
    println((2147483648L).toInt()) // 1 more overflows it to the min (negative) 32 bit signed int
    println((2147483649L).toInt()) // 2 more...
    println((Long.MAX_VALUE - 1).toInt())
    println((Long.MAX_VALUE).toInt())

приводит к:

2147483647
-2147483648
-2147483647
-2
-1

От: https://discuss.kotlinlang.org/t/checked-and-unsigned-integer-operations/529/2

Исключения при арифметическом переполнении: это, вероятно, значительно замедлит арифметику, и мы не видим, как ее избежать без изменений в JVM, и мы не готовы принять замедление

2 голосов
/ 25 апреля 2019

Если вы работаете на JVM, вы можете использовать Math.toIntExact:

Возвращает значение длинного аргумента;выдает исключение, если значение переполняет целое число.

Кажется, что нет чистого способа Котлина, но по крайней мере вы можете его обернуть:

fun Long.toIntExact() = Math.toIntExact(this)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...