Kotlin - 带有溢出异常的类型转换

ser*_*0ne 2 type-conversion kotlin

(123L).toInt()生产123Long.MAX_VALUE.toInt()生产-1。显然这是不正确的。无需编写大量样板代码,当值超出目标类型的范围/界限时,有没有办法让 Kotlin 抛出异常?

小智 5

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()
}
Run Code Online (Sandbox Code Playgroud)

您观察到的“奇怪”行为正在发生,因为在 Kotlin 中,Long 表示为 64 位有符号整数,而 Int 表示为 32 位有符号整数。

虽然 123L 很容易用 32 位整数表示,但 Long.MAX_VALUE 会使整数溢出(几乎)两次,从而导致您正在观察的行为。

我相信下面的例子会更好地说明它:

    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())
Run Code Online (Sandbox Code Playgroud)

结果是 :

2147483647
-2147483648
-2147483647
-2
-1
Run Code Online (Sandbox Code Playgroud)

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

算术溢出异常:这可能会使算术显着变慢,而且我们不知道如何在不改变 JVM 的情况下避免它,我们也没有准备好接受减速