无符号数实现为具有单个存储属性的
内联类
,
该属性类型为与其宽度相同的对应有符号类型。 If you want to convert between unsigned and signed integer types,
make sure you update your code so that any function calls and operations support the new type.
无符号数组与区间
无符号数组及其对应操作处于
Beta
状态。 它们可能随时进行不兼容变更。
需要选择加入(详见下文)。
与原生类型相同,每个无符号类型都有表示相应类型数组的类型:
UByteArray
: 无符号字节数组。
UShortArray
: 无符号短整型数组。
UIntArray
: 无符号整型数组。
ULongArray
: 无符号长整型数组。
与有符号整型数组一样,它们提供了类似于
Array
类的 API 而没有装箱开销。
When you use unsigned arrays, you receive a warning that indicates that this feature is not stable yet.
To remove the warning, opt-in with the
@ExperimentalUnsignedTypes
annotation.
It's up to you to decide if your clients have to explicitly opt-in into usage of your API, but keep in mind that unsigned
arrays are not a stable feature, so an API that uses them can be broken by changes in the language.
Learn more about opt-in requirements
.
区间与数列
也支持
UInt
与
ULong
(通过这些类
UIntRange
、
UIntProgression
、
ULongRange
、
ULongProgression
)。 Together with the unsigned integer types, these classes are stable.
无符号整数字面值
为使无符号整型更易于使用,Kotlin 提供了用后缀标记整型字面值来
表示指定无符号类型(类似于
Float
或
Long
):
u
and
U
tag is for unsigned literals. The exact type is determined based on the expected type.
If no expected type is provided, compiler will use
UInt
or
ULong
depending on the size of literal:
val b: UByte = 1u
val s: UShort = 1u
val l: ULong = 1u
val a1 = 42u
val a2 = 0xFFFF_FFFF_FFFFu
uL
与 UL
显式将字面值标记为无符号长整型:
val a = 1UL
The main use case of unsigned numbers is utilizing the full bit range of an integer to represent positive values.
For example, to represent hexadecimal constants that do not fit in signed types such as color in 32-bit AARRGGBB
format:
data class Color(val representation: UInt)
val yellow = Color(0xFFCC00CCu)
You can use unsigned numbers to initialize byte arrays without explicit toByte()
literal casts:
val byteOrderMarkUtf8 = ubyteArrayOf(0xEFu, 0xBBu, 0xBFu)
Another use case is interoperability with native APIs. Kotlin allows representing native declarations that contain
unsigned types in the signature. The mapping won't substitute unsigned integers with signed ones keeping the semantics unaltered.
While unsigned integers can only represent positive numbers and zero, it's not a goal to use them where application
domain requires non-negative integers. For example, as a type of collection size or collection index value.
There are a couple of reasons:
Using signed integers can help to detect accidental overflows and signal error conditions, such as
List.lastIndex
being -1 for an empty list.
Unsigned integers cannot be treated as a range-limited version of signed ones because their range of values is not a
subset of the signed integers range. Neither signed, nor unsigned integers are subtypes of each other.