4.3 基礎類型
Kotlin中,所有都是對象是因爲我們可以調用任何對象的成員函數和屬性。有一些類型是內建的,因爲這些類型的實現是優化過的,但是使用的時候看起來和普通類是一樣的。本節中我們將介紹這些類型:數據類型,字符類型,布爾類型和數組。(number, character, boolean 和array)
數據類型 numbers
Kotlin中處理數據類型和Java方法很類似,但也不完全一樣。例如,沒有隱式地擴展數據類型字長,還有寫法上也稍有不同。
Kotlin提供下面這些內置的數據類型來表示數字,這和Java很接近。
Type | Bit width |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
注意字符類型不在數據類型中。
字符常量 Literal Constants
有如下幾種給整數值的字符常量
- 十進制:
123
- 長整型帶L
123L
- 長整型帶L
- 16進製表示:
0x0F
- 二進制:
0b00001011
注意:不支持八進制表示
Kotlin還支持浮點數的表示
- 默認是Double類型 : 123.5
, 123.5e10
- Float 類型的要加上標記f
或者F
:123.5f
數字表示中的下劃線(從v1.1開始)
可以在比較長的數字中間加上下劃線,這樣更容易閱讀
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecutiryNumber = 999_999_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 = 1000
print (a == a) // Prints 'true'
val boxedA: Int = a
val anotherBexedA: Int = a
print(boxedA == anotherBoxedA) // Prints 'true'
顯式轉換
由於不同的表達方式, 值域範圍小的類型不是值域範圍大的類型的子類型。
Kotlin不支持隱式轉換:
val b: Byte = 1 // Ok
val i: Int = b // Error
可以顯式轉換:
val b: Byte = 1
val i: int = b.toInt() // OK, 顯式的轉換
每一種數值類型都支持如下轉換操作:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
缺少隱式轉換很難被發現,因爲類型是根據上下文推斷的,並且算數操作符都被重載成適合改轉換的。
val longNumber = 1L + 3 // Long + Int >= Long
操作符
kotlin支持標準的算數操作符,他們被定義成對應類的成員函數。編譯器會把對應的函數調用優化成對應的指令。 詳見 Operator overlading。
對於比特位的操作,沒有定義特殊字符給這些運算符,只是用可以被內置的方式來命名這些函數。例如
val x = (1 shl 2) and 0x0000_FF00
下面是支持全部的比特操作(僅對Int
和Long
類型支持)
shl(bits)
-帶符號左移位,相當於(Java 的<<
)shr(bits)
-帶符號右移位,相當於(Java的>>
)ushl(bits)
-不帶符號左移位,相當於(Java 的<<<
)ushr(bits)
-不帶符號右移位,相當於(Java 的>>>
)and(bits)
-按位與, 相當於(Java 的&
)or(bits)
-按位或, 相當於(Java 的|
)xor(bits)
-按位異或, 相當於(Java 的^
)inv()
-按位取反, 相當於(Java 的~
)
字符類型
Kotlin中字符是用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()
}
和數值一樣,可以爲空的引用會觸發自動封箱。 這種情況下,不保證一致性。
布爾類型
布爾類型用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()
來創建一個指定大小的空數組
還可以使用一個工廠函數,包含數組大小和一個可以根據座標返回每個元素初始值的函數:
// 創建一個Array<String> ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() }
可以用[]
來訪問數組,相當於調用了get()
和set()
注意:和Java中的數組不同,Kotlin中的數組是不可變的。這意味着在Kotlin中不允許我們把一個
Array<String>
賦值給一個Array<Any>
, 這樣可以防止可能的運行時錯誤。(但是可以使用Array<outAny>
, 詳見Type Projections)
Kotin 還有定製的類來表示基礎數據類型的數組來避免封箱帶來的額外的開銷,他們包括ByteArray
, ShortArray
, IntArray
等等。 這些類和Array
沒有繼承關係,但是他們有同樣的函數接口和屬性接口。每一個都有對應的工廠方法。
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串 Strings
字符串是用Strings
這個類來表示的。 字符串是不可變的。字符串的單個字符可以通過座標操作來訪問: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 = val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
"""
val trimed = text.trimMargin()
println($trimed)
輸出是
Tell me and I forget.
Teach me and I remember.
Involve me and I learn.
(Benjamin Franklin)
默認參數是|
也可以使用其他字符。
字符串模板
字符串可以包含字符串模板表達式,例如代碼可以判斷哪些字符要被輸出到字符串結果。一個模板表達式是用美元符開始$
,包含一個簡單變量名
val i = 10
val s = "i = $i" // "i = 10"
或者是接一個在{}
中的完整表達式
val s = "abc"
val str = "$s.length is ${s.length}" // "abc.length is 3"
字符串模板,在元字符串和轉義字符串中都可以使用。
如果想要在元字符串中(元字符串不支持反斜線轉義)使用美元符$
,可以使用如下寫法。
val price = """
${'$'}9.99
"""