(123L).toInt()
产生123
,但是Long.MAX_VALUE.toInt()
产生-1
。显然这是不正确的。无需编写大量样板代码,是否有一种方法可以使Kotlin在目标类型的值超出范围/范围时引发异常?
答案 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的情况下,我们看不到如何避免这种情况,我们也未准备好接受这种变慢