在Kotlin中,一切都是一个对象,可以在任何变量上调用成员函数和属性。 一些类型是内置的,因为它们的实现被优化,但是它们看起来像普通类。 在本节中,我们将介绍描述Kotlin中的大多数类型:数字,字符,布尔和数组等等。
Kotlin以接近Java的方式来处理数字,但不完全相同。 例如,数字没有隐含的扩展转换,在某些情况下,字面量略有不同。
Kotlin提供以下代表数字的内置类型(这接近Java):
类型 | 位宽度 |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
123
123L
0x0F
0b00001011
Kotlin还支持一个常规的浮点数符号:
Double
:123.5
, 123.5e10
f
或F
:123.5f
可以使用下划线使数字常量更易读:
val oneMillion = 1_000_000 val creditCardNumber = 1234_5678_9012_3456L val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010表示
在Java平台上,数字被物理存储为JVM原始类型,除非需要一个可空的数字引用(例如Int?
)或涉及泛型。 在后一种情况下,数字是装箱的。
请注意,装箱数字不一定保持身份:
val a: Int = 10000 print(a === a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA === anotherBoxedA) // !!!Prints 'false'!!!另一方面,它保持相等:
val a: Int = 10000 print(a == a) // Prints 'true' val boxedA: Int? = a val anotherBoxedA: Int? = a print(boxedA == anotherBoxedA) // Prints 'true'显式转换
由于不同的表示,较小的类型不是较大的类型的子类型,就会有以下类型的麻烦:
// Hypothetical code, does not actually compile: val a: Int? = 1 // A boxed Int (java.lang.Integer) val b: Long? = a // implicit conversion yields a boxed Long (java.lang.Long) print(a == b) // Surprise! This prints "false" as Long's equals() check for other part to be Long as well
因此,较小的类型不会被隐式转换为更大的类型。 这意味着不能在没有显式转换的情况下将Byte
类型的值赋给Int
类型的变量。
val b: Byte = 1 // OK, literals are checked statically val i: Int = b // ERROR可以使用显式转换来扩宽数字 -
val i: Int = b.toInt() // OK: explicitly widened每个数字类型都支持以下转换:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
val l = 1L + 3 // Long + Int => Long
Kotlin支持对数字进行的算术运算的标准集合,它们被声明为适当类的成员(但编译器将调用优化为相应的指令)。请参阅操作符重载。
对于按位操作,它们没有特殊的字符,但是只能命名为可以以中缀形式调用的函数,例如:
val x = (1 shl 2) and 0x000FF000
以下是按位操作的完整列表(仅适用于Int
和Long
):
shl(bits)
– 有符号向左移 (Java的<<
)
shr(bits)
– 有符号向右移 (Java’s >>)
ushr(bits)
– 无符号向右移 (Java’s >>>)
and(bits)
– 位运算符and
or(bits)
– 位运算符or
xor(bits)
– 位运算符xor
inv()
– 位运算符”取反”
fun check(c: Char) { if (c == 1) { // ERROR: incompatible types // ... } }字符文字用单引号表示:
'1'
。 可以使用反斜杠转义特殊字符。 支持以下转义序列:\t
,\b
,\n
,\r
,\'
,\"
,\\
和\$
; 要编码任何其他字符,请使用Unicode转义序列语法:'\uFF00'
。
可以将一个字符显式转换为一个Int
类型数字:
fun decimalDigitValue(c: Char): Int { if (c !in '0'..'9') throw IllegalArgumentException("Out of range") return c.toInt() - '0'.toInt() // Explicit conversions to numbers }
像数字一样,当需要可空引用时,字符将被包装。标识不能被装箱操作所保留。
Boolean
类型表示布尔值,并具有两个值:true
和false
。
如果需要可空引用,布尔值将可被装箱。
内置的布尔操作包括:
||
– 懒分离
&&
– 懒结合
!
- 否定
Array
类表示,它有get()
和set()
函数(通过运算符重载约定转换为[]
),以及size
属性以及其他一些有用的成员函数:
class Array<T> private constructor() { val size: Int operator fun get(index: Int): T operator fun set(index: Int, value: T): Unit operator fun iterator(): Iterator<T> // ... }
要创建一个数组,我们可以使用一个库函数arrayOf()
,并将数组的元素值传递给它,如:arrayOf(1,2,3)
创建一个数组[1,2,3]
。 或者arrayOfNulls()
库函数可用于创建一个填充空(null
)元素的给定大小的数组。
另一个选择是使用一个工厂函数,它使用数组大小和返回给定其索引的每个数组元素的初始值的函数:
// Creates an Array<String> with values ["0", "1", "4", "9", "16"] val asc = Array(5, { i -> (i * i).toString() })
如上所述,[]
操作代表调用成员函数get()
和set()
。
注意:与Java不同,Kotlin中的数组是不变的。 这意味着Kotlin不允许将Array <String>
分配给Array <Any>
,这样可以防止可能的运行时故障(但可以使用Array <out Any>
),详细的可参考类型投影。
Kotlin还有专门的类来表示原始类型的数组,没有装箱开销,它们分别是:ByteArray
, ShortArray
, IntArray
等等。
这些类与Array
类没有继承关系,但它们具有相同的方法和属性集。它们也有相应的工厂函数:
val x: IntArray = intArrayOf(1, 2, 3) x[0] = x[1] + x[2]
String
类型表示。字符串是不可变的。 字符串的元素可以通过索引操作的字符:s[i]
来访问。可以使用for
循环迭代字符串:
for (c in str) { println(c) }
Kotlin有两种类型的字符串字面值:可以在其中转义字符的转义字符串,以及可以包含换行符和任意文本的原始字符串。 转义的字符串非常像Java字符串:
val s = "Hello, world!\n"
使用反斜杠以常规方式完成转义。 有关支持的转义序列的列表,请参阅上述字符。
原始字符串由三重引号("""
)分隔,不包含转义,并且可以包含换行符和任何其他字符:
val text = """ for (c in "foo") print(c) """可以使用
trimMargin()
函数删除前导空格:
val text = """ |Tell me and I forget. |Teach me and I remember. |Involve me and I learn. |(Benjamin Franklin) """.trimMargin()
字符串可以包含模板表达式,即被评估的代码片段,并且其结果被连接到字符串中。 模板表达式以美元符号($
)开头以及简单名称组成:
val i = 10 val s = "i = $i" // evaluates to "i = 10"或大括号中的任意表达式:
val s = "abc" val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
原始字符串和转义字符串内部都支持模板。如果您需要在原始字符串(不支持反斜杠转义)中表示一个文字$
字符,则可以使用以下语法:
val price = """ ${'$'}9.99 """