Числовые типы в Kotlin: представление, явные преобразования

Представление

На платформе Java числа физически хранятся в виде примитивных типов JVM, если только нам не нужна ссылка на обнуляемое число (например, Int?) Или не используются дженерики. В последних случаях числа имеют обертку.

Обратите внимание, что обертывание чисел не обязательно сохраняет идентичность:

val a: Int = 10000
println(a === a) // Печатает 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA === anotherBoxedA) // !!!Печатает 'false'!!!

С другой стороны, это сохраняет равенство:

val a: Int = 10000
println(a == a) // Печатает 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
println(boxedA == anotherBoxedA) // Печатает 'true'

Явные преобразования

Из-за разных представлений меньшие типы не являются подтипами больших. Если бы они были, у нас были бы проблемы следующего вида:

// Гипотетический код, на самом деле не компилируется:

val a: Int? = 1 // обернутый Int (java.lang.Integer)
val b: Long? = a // неявное преобразование дает обернутый Long (java.lang.Long)
print(b == a) // Сюрприз! Это печатает "false", поскольку equals() Long проверяет, 
              // является ли другое число тоже Long

Так что равенство было бы молча потеряно повсюду, не говоря уже о идентичности.

Как следствие, меньшие типы преобразуются в большие типы только явно. Это означает, что мы не можем присвоить значение типа Byte переменной Int без явного преобразования

val b: Byte = 1 // OK, литералы проверяются статически
val i: Int = b // ОШИБКА

Мы можем использовать явные преобразования, чтобы расширить числа

val i: Int = b.toInt() // OK: явно расширено
print(i)

Каждый числовой тип поддерживает следующие преобразования:

  • toByte(): Byte
  • toShort(): Short
  • toInt(): Int
  • toLong(): Long
  • toFloat(): Float
  • toDouble(): Double
  • toChar(): Char

Отсутствие неявных преобразований редко заметно, поскольку тип выводится из контекста, а арифметические операции перегружаются, например, для соответствующих преобразований.

val l = 1L + 3 // Long + Int => Long


Читайте также:


Комментарии

Популярные сообщения из этого блога

Строки в Kotlin

Наследование в Kotlin

Возврат и прыжки в Kotlin