歡迎關(guān)注 二師兄Kotlin
轉(zhuǎn)載請注明出處 二師兄kotlin
基本數(shù)據(jù)類型
在kotlin中徙融,一切皆對象斩启,對于一個(gè)變量祷愉,我們可以調(diào)用它的任何成員函數(shù)和屬性。某些數(shù)據(jù)類型是語言內(nèi)建的酬姆,它們的實(shí)現(xiàn)都做了優(yōu)化,但使用起來跟一般的類沒有任何區(qū)別奥溺。本小節(jié)將講解它們中的大部分辞色,例如:numbser, characters, booleans和arrays。
數(shù)字(Numbers)
Kotlin中處理數(shù)字的方式和Java很像浮定,但不完全一樣相满。例如:不能顯式的向上擴(kuò)展數(shù)字;字面常量在某些情況下稍微不同桦卒。
Kotlin提供以下內(nèi)建類型表示數(shù)字(這與Java很相似):
Type | Bit Width |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
注意:在Kotlin中字符(charactors)不是數(shù)字立美。
字面常量
下面是所有類型的字面常量:
- 小數(shù)(Decimals):123
- 長整型以大寫的L結(jié)尾:123L
- 16進(jìn)制以0x開頭:0x0F
- 2進(jìn)制以0b開頭:0b00001011
注意:8進(jìn)制不支持
包裝類
Java中,數(shù)字一般作為Jvm基本數(shù)據(jù)類型存儲(chǔ)方灾,除非我們需要一個(gè)null引用(e.g. ==Int?==)或者作為泛型使用建蹄。用作泛型時(shí)就必須做裝箱操作。
注意:數(shù)字的裝箱操作不會(huì)保留數(shù)字標(biāo)識(shí):
val a: Int = 10000
print(a === a) // Prints 'true'
val boxedA: Int? = a
val anothorBoxedA: 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'
顯式轉(zhuǎn)換
由于不同包裝類的存在躲撰,較小的類型并不是教大類型的子類型。如果是的話击费,我們將遇到下面這種類型的麻煩:
//假設(shè)的代碼拢蛋,實(shí)際不能編譯
val a: Int? = 1 // Int裝箱 (java.lang.Integer)
val b: Long? = a // 隱式轉(zhuǎn)換生成一個(gè)Long裝箱類型 (java.lang.Long)
print(a == b) // 很奇怪! 這里會(huì)打印"false",因?yàn)長ong只能和Long比較
所以不僅是數(shù)字標(biāo)識(shí)蔫巩,甚至連值的等價(jià)性都在所有的地方毫無征兆的消失了谆棱。
結(jié)論是,較小的數(shù)字類型不能隱式轉(zhuǎn)換為較大的數(shù)字類型圆仔。這意味著我們不能把Byte類型的值賦給Int類型的變量垃瞧,除非顯式聲明。
val b: Byte = 1 // 正確, 字面常量會(huì)被靜態(tài)檢查
val i: Int = b // 錯(cuò)誤
我們可以通過顯式轉(zhuǎn)換增加精度
val i: Int = b.toInt() // 正確坪郭,顯式提升精度
所有的數(shù)字類型(Number)都支持一下的轉(zhuǎn)換:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
隱式轉(zhuǎn)換并不需要特別的注意个从,因?yàn)轭愋蜁?huì)根據(jù)上下文自行推斷,而算術(shù)運(yùn)算符也做了合適的重載以適應(yīng)不同類型的轉(zhuǎn)換,例如
val l = 1L + 3 // Long + Int => Long
操作符
Kotlin支持標(biāo)準(zhǔn)的算術(shù)運(yùn)算符嗦锐,這些操作符都已經(jīng)聲明為各個(gè)數(shù)字類的成員變量(但是編譯器會(huì)根據(jù)相關(guān)原則針對調(diào)用作出優(yōu)化)嫌松。詳情請看操作符重載。
對于位運(yùn)算符奕污,沒有特別的符號(hào)萎羔,只有相關(guān)的函數(shù)以中綴的形式調(diào)用,例如:
val x = (1 shl 2) and 0x000FF000
這里是所有可用的位操作(只能用于Int和Long):
-
shl(bits)
– 帶符號(hào)左移(對應(yīng)Java <<) -
shr(bits)
– 帶符號(hào)右移(對應(yīng)Java >>) -
ushr(bits)
– 無符號(hào)右移(對應(yīng)Java >>>) -
and(bits)
– 按位與 -
or(bits)
– 按位或 -
xor(bits)
– 按位異或 -
inv()
– 按位求反
字符
字符用Char表示碳默,不能當(dāng)數(shù)字對待贾陷。
fun check(c: Char) {
if (c == 1) { // 錯(cuò)誤: 不兼容的類型
// ...
}
}
字符字面常量用單引號(hào):'1'。特殊字符用反斜杠轉(zhuǎn)義嘱根。支持以下轉(zhuǎn)義字符: \t
, \b
, \n
, \r
, \'
, \"
, \\
and \$
髓废。對于其他編碼字符使用Unicode轉(zhuǎn)義語法:'\uFF00'
.
我們可以顯式的把一個(gè)字符轉(zhuǎn)成Int類型的數(shù)字:
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 顯式轉(zhuǎn)換成數(shù)字
}
像數(shù)字(Numbers)一樣,當(dāng)需要null引用時(shí)儿子,字符也可以被裝箱瓦哎,此時(shí)字符標(biāo)識(shí)也同樣不會(huì)被保留。
布爾值
類型Boolean
表示布爾類型柔逼,有兩種值true
和false
蒋譬。
如果需要null引用也可以被裝箱。
內(nèi)建的布爾操作符包括:
- ||
- &&
- !
數(shù)組
數(shù)組在Kotlin中用Array
類表示愉适,它有get
和set
函數(shù)(按照習(xí)慣[]
已做了操作符重載)犯助,和size
屬性,還有其他幾個(gè)有用的成員函數(shù):
class Array<T> private constructor() {
val size: Int
fun get(index: Int): T
fun set(index: Int, value: T): Unit
fun iterator(): Iterator<T>
// ...
}
生成數(shù)組维咸,可以使用庫函數(shù)arrayOf()
傳入每一項(xiàng)的值剂买,所以arrayOf(1, 2, 3)
產(chǎn)生一個(gè)數(shù)組[1, 2, 3]。另外一個(gè)庫函數(shù)arrayOfNulls()
可以產(chǎn)生一個(gè)用null填充的指定長度的數(shù)組癌蓖。
另外一種選擇是使用工廠函數(shù)根據(jù)指定的長度瞬哼,根據(jù)索引和規(guī)則初始化數(shù)組的每一項(xiàng):
// 生成一個(gè)Array<String>的數(shù)組, 值為["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
如我們上文所說租副,操作符[]
相當(dāng)于調(diào)用了函數(shù)get
和set
坐慰。
注意:與java不同的是,kotlin中的數(shù)組是不可變的用僧。這意味這我們不能把Array<String>
賦值給Array<Any>
, 這避免了一種可能的運(yùn)行時(shí)錯(cuò)誤(但是你可以用Array<out Any>
, 參考類型映射)结胀。
Kotlin也有特殊的類代表沒有裝箱的基本數(shù)據(jù)類型數(shù)組:ByteArray
, ShortArray
, IntArray
等等。這些類沒與Array
類沒有繼承關(guān)系责循,但是它們有相同的成員函數(shù)和屬性糟港,每一個(gè)也都有對應(yīng)的工廠函數(shù):
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
字符串
字符串用String
表示。字符串是不可變的院仿,字符串中的元素是字符秸抚,可以通過索引訪問:s[i]
速和。字符串可以用for-loop迭代遍歷:
for (c in str) {
println(c)
}
字符串字面量
Kotlin有兩種字符串字面常量:轉(zhuǎn)義字符串可能包含轉(zhuǎn)義字符;原生字符串可以包含換行符和任意常規(guī)字符耸别。轉(zhuǎn)義字符串非常像Java字符串:
val s = "Hello, world!\n"
轉(zhuǎn)義沿用習(xí)慣健芭,用反斜杠。
原生字符串使用三個(gè)雙引號(hào)隔開秀姐,可以包含沒有轉(zhuǎn)義的、換行符和任意其他字符:
val text = """
for (c in "foo")
print(c)
"""
你可以使用 trimMargin()
函數(shù)移除開頭的空格:
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
默認(rèn)情況下使用|
用作邊界前綴若贮,但是你可以使用其他字符省有,然后作為參數(shù)傳進(jìn)去,例如trimMargin(">")
谴麦。
字符串模版
字符串可以包含模板表達(dá)式蠢沿,例如求一段代碼的值,然后把結(jié)果和一段字符串聯(lián)系在一起匾效。模板表達(dá)式以$開頭外加一個(gè)變量名舷蟀,如:
val i = 10
val s = "i = $i" // 計(jì)后得到 "i = 10"
或者一個(gè)用大括號(hào)包裹的常規(guī)表達(dá)式:
val s = "abc"
val str = "$s.length is ${s.length}" // 計(jì)算得到 "abc.length is 3"
轉(zhuǎn)義字符串和原生字符串都支持模板。如果你需要在原生字符串中顯示$
字符面哼,可以用下面的辦法:
val price = """
${'$'}9.99
"""