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

时间:2019-04-24 21:05:22

标签: kotlin type-conversion

(123L).toInt()产生123,但是Long.MAX_VALUE.toInt()产生-1。显然这是不正确的。无需编写大量样板代码,是否有一种方法可以使Kotlin在目标类型的值超出范围/范围时引发异常?

2 个答案:

答案 0 :(得分:2)

如果您在JVM上运行,则可以使用Math.toIntExact

  

返回long参数的值;如果该值溢出一个int,则抛出异常。

似乎不是纯粹的Kotlin方式,但至少您可以很好地包装它:

fun Long.toIntExact() = Math.toIntExact(this)

答案 1 :(得分:2)

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的情况下,我们看不到如何避免这种情况,我们也未准备好接受这种变慢