在 Kotlin 中,所有东西都是对象,可以在任何变量上调用成员函数与属性;一些类型可以有特殊的内部表示,数字、字符以及布尔可以在运行时表示为原生类型值,但对用户而言像普通类。
1、整数类型
类型 | 大小(比特数) | 最小值 | 最大值 |
---|---|---|---|
Byte | 8 | -128 | 127 |
Short | 16 | -32768 | 32767 |
Int | 32 | -2,147,483,648 (-231) | 2,147,483,647 (231 - 1) |
Long | 64 | -9,223,372,036,854,775,808 (-263) | 9,223,372,036,854,775,807 (263 - 1) |
如需显式指定 Long
值,请给该值追加后缀 L
val oneLong = 1L // Long
2、浮点类型
类型 | 大小(比特数) | 有效数字比特数 | 指数比特数 | 十进制位数 |
---|---|---|---|---|
Float | 32 | 24 | 8 | 6-7 |
Double | 64 | 53 | 11 | 15-16 |
小数部分与整数部分之间用句点(.
)分隔 对于以小数初始化的变量,编译器会推断为 Double
类型
val pi = 3.14 // Double
如需将一个值显式指定为 Float
类型,请添加 f
或 F
后缀。 如果这样的值包含多于 6~7 位十进制数,那么会将其舍入
val e = 2.7182818284 // Double
val eFloat = 2.7182818284f // Float,实际值为 2.7182817
Kotlin 中的数字没有隐式拓宽转换。 例如,具有 Double
参数的函数只能对 Double
值调用,而不能对 Float
、 Int
或者其他数字值调用
fun printDouble(d: Double) { print(d) }
val i = 1
val d = 1.0
val f = 1.0f
printDouble(d)
// printDouble(i) // 错误:类型不匹配
// printDouble(f) // 错误:类型不匹配
3、数字字面常量
- 十进制:
123
- Long 类型用大写
L
标记:123L
- Long 类型用大写
- 十六进制:
0x0F
- 二进制:
0b00001011
- 八进制: 不支持
- 默认 double:
123.5
、123.5e10
- Float 用
f
或者F
标记:123.5f
4、JVM平台数字表示
在 JVM 平台数字存储为原生类型 int
、 double
等; 例外情况是当创建可空数字引用如 Int?
或者使用泛型时,数字会装箱为 Java 类 Integer
、 Double
等
5、显式数字转换
所有数字类型都支持转换为其他类型:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
较小的类型不能 隐式转换为较大的类
val b: Byte = 1 // OK, 字面值会静态检测
// val i: Int = b // 错误
val i1: Int = b.toInt()
很多情况都不需要显式类型转换,因为类型会从上下文推断出来, 而算术运算会有重载做适当转换
val l = 1L + 3 // Long + Int => Long
6、数字运算
Kotlin支持数字运算的标准集:+
、 -
、 *
、 /
、 %
,它们已定义为相应的类成员
整数间的除法总是返回整数,会丢弃任何小数部分,如需返回浮点类型,请将其中的一个参数显式转换为浮点类型
val x = 5 / 2.toDouble()
7、位运算
位运算列表:
shl(bits)
– 有符号左移shr(bits)
– 有符号右移ushr(bits)
– 无符号右移and(bits)
– 位与or(bits)
– 位或xor(bits)
– 位异或inv()
– 位非
只能应用于 Int
与 Long的
中缀形式调用的函数表示
val x = (1 shl 2) and 0x000FF000
8、浮点数比较
静态类型
- 相等性检测:
a == b
与a != b
- 比较操作符:
a < b
、a > b
、a <= b
、a >= b
- 区间实例以及区间检测:
a..b
、x in a..b
、x !in a..b
泛型
- 认为
NaN
与其自身相等 - 认为
NaN
比包括正无穷大(POSITIVE_INFINITY
)在内的任何其他元素都大 - 认为
-0.0
小于0.0
静态类型作为浮点数 (Double.NaN
)的操作数与静态类型并非作为浮点数的操作数(listOf(T)
)之间的行为差异
// 静态类型作为浮点数的操作数
println(Double.NaN == Double.NaN) // false
// 静态类型并非作为浮点数的操作数
// 所以 NaN 等于它本身
println(listOf(Double.NaN) == listOf(Double.NaN)) // true
// 静态类型作为浮点数的操作数
println(0.0 == -0.0) // true
// 静态类型并非作为浮点数的操作数
// 所以 -0.0 小于 0.0
println(listOf(0.0) == listOf(-0.0)) // false
println(listOf(Double.NaN, Double.POSITIVE_INFINITY, 0.0, -0.0).sorted())
// [-0.0, 0.0, Infinity, NaN]