Kotlin數據類型
在Kotlin中,一切都是一個對象,可以在任何變量上調用成員函數和屬性。 一些類型是內置的,因爲它們的實現被優化,但是它們看起來像普通類。 在本節中,我們將介紹描述Kotlin中的大多數類型:數字,字符,布爾和數組等等。
數字類型
Kotlin以接近Java的方式來處理數字,但不完全相同。 例如,數字沒有隱含的擴展轉換,在某些情況下,字面量略有不同。
Kotlin提供以下代表數字的內置類型(這接近Java):
類型
位寬度
Double
64
Float
32
Long
64
Int
32
Short
16
Byte
8
注意,字符不是Kotlin中的數字。
字面常量/文字常量
對於整數值,有以下幾種字面常量:
- 整數:
123
- 長整數由大寫L標記:
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()
– 位運算符」取反」
字符
字符由Char類型表示,它們不能直接被視爲數字
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
。
如果需要可空引用,布爾值將可被裝箱。
內置的布爾操作包括:
-
||
– 懶分離 -
&&
– 懶結合 -
!
- 否定
數組
Kotlin中的數組由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()
默認使用|
作邊距前綴,但您可以選擇另一個字符,並將其作爲參數傳遞: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
"""