正式上架:《Kotlin極簡(jiǎn)教程》Official on shelves: Kotlin Programming minimalist tutorial
京東JD:https://item.jd.com/12181725.html
天貓Tmall:https://detail.tmall.com/item.htm?id=558540170670
在 Kotlin 中,所有東西都是對(duì)象:數(shù)字、字符、布爾和數(shù)組。(JavaScript)
數(shù)字
Kotlin 提供了如下的內(nèi)置類型來表示數(shù)字(長(zhǎng)度bit):
Double(64)
Float(32)
Long(64)
Int(32)
Short(16)
Byte(8)
在 Kotlin 中字符不是數(shù)字字面常量。
數(shù)值常量字面值有以下幾種:
十進(jìn)制: 123
Long 類型用大寫 L
標(biāo)記: 123L
十六進(jìn)制: 0x0F
二進(jìn)制: 0b00001011
注意: 不支持八進(jìn)制
Kotlin 同樣支持浮點(diǎn)數(shù)的常規(guī)表示方法:
double:123.5, 123.5e10
Float 用 f 或者 F
標(biāo)記: 123.5f
每個(gè)數(shù)字類型支持如下的轉(zhuǎn)換:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
缺乏隱式類型轉(zhuǎn)換并不顯著,因?yàn)轭愋蜁?huì)從上下文推斷出來,而算術(shù)運(yùn)算會(huì)有重載做適當(dāng)轉(zhuǎn)換,例如:
val l = 1L + 3 // Long + Int => Long
布爾類型
Boolean,它有兩個(gè)值:true 和 false。
若需要可空引用布爾會(huì)被裝箱。
內(nèi)置的布爾運(yùn)算有:
|| 短路邏輯或
&& 短路邏輯與
! 邏輯非
數(shù)組
數(shù)組在 Kotlin 中使用 Array類來表示,它定義了 :
get和 set函數(shù)(按照運(yùn)算符重載約定這會(huì)轉(zhuǎn)變?yōu)?[])
size屬性
以及一些其他有用的成員函數(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ù) arrayOf()
來創(chuàng)建一個(gè)數(shù)組并傳遞元素值給它,這樣
arrayOf(1, 2, 3)
創(chuàng)建了 array [1, 2, 3]。
或者,庫函數(shù) arrayOfNulls().
可以用于創(chuàng)建一個(gè)指定大小、元素都為空的數(shù)組。
另一個(gè)選項(xiàng)是用接受數(shù)組大小和一個(gè)函數(shù)參數(shù)的工廠函數(shù),用作參數(shù)的函數(shù)能夠返回 給定索引的每個(gè)元素初始值:
// 創(chuàng)建一個(gè) Array<String> 初始化為 ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
如上所述,[] 運(yùn)算符代表調(diào)用成員函數(shù) get() 和 set()
Kotlin 也有無裝箱開銷的專門的類來表示原生類型數(shù)組:
ByteArray
ShortArray
IntArray
等等。
這些類和 Array并沒有繼承關(guān)系,但是 它們有同樣的方法屬性集。它們也都有相應(yīng)的工廠方法:
val x: IntArray = intArrayOf(1, 2, 3)x[0] = x[1] + x[2]
字符串
字符串用 String類型表示。字符串是不可變的。 字符串的元素——字符可以使用索引運(yùn)算符訪問:
s[i]
可以用 for 循環(huán)迭代字符串:
for (c in str) { println(c)}
字符串模板
字符串可以包含模板表達(dá)式 ,即一些小段代碼,會(huì)求值并把結(jié)果合并到字符串中。 模板表達(dá)式以美元符($)開頭,由一個(gè)簡(jiǎn)單的名字構(gòu)成:
val i = 10
val s = "i = $i" // 求值結(jié)果為 "i = 10"
或者用花括號(hào)擴(kuò)起來的任意表達(dá)式:
val s = "abc"
val str = "$s.length is ${s.length}" // 求值結(jié)果為 "abc.length is 3"
原生字符串和轉(zhuǎn)義字符串內(nèi)部都支持模板。
基本類型
在Kotlin中,所有東西都是對(duì)象,所以我們可以調(diào)用成員函數(shù)和屬性的任何變量對(duì)象。有些類型是內(nèi)置的,他們的實(shí)現(xiàn)被優(yōu)化過, 但是用戶看起來他們就像普通的類. 本節(jié)我們會(huì)描述這些類型: numbers, characters, booleans 和 arrays.
Numbers
Kotlin處理numbers和Java很接近,但是并不完全相同. 例如, 對(duì)于numbers沒有隱式擴(kuò)大轉(zhuǎn)換(如java中int可以隱式變?yōu)閘ong),在一些情況下文字的使用有所不同.
對(duì)于numbers Kotlin提供了如下的內(nèi)置類型 (與Java很相近):
| Type | Bitwidth |
|---|---|
| Double | 64 |
| Float | 32 |
| Long | 64 |
| Int | 32 |
| Short | 16 |
| Byte | 8 |
注意在kotlin中 characters 不是 numbers
字面量
下面是一些常量的寫法:
- 十進(jìn)制:
123- Longs類型用大寫
L標(biāo)記:123L
- Longs類型用大寫
- 十六進(jìn)制:
0x0F - 二進(jìn)制:
0b00001011
注意: 不支持8進(jìn)制
Kotlin 同樣支持浮點(diǎn)數(shù)的常規(guī)表示方法:
- Doubles
123.5,123.5e10 - Floats用
f或者F標(biāo)記:123.5f
存儲(chǔ)方式
在Java平臺(tái)數(shù)字是物理存儲(chǔ)為JVM的原始類型,除非我們需要一個(gè)可空的引用(例如int?)或泛型. 后者情況下數(shù)字被裝箱(指的是賦值的時(shí)候把實(shí)例復(fù)制了一下,不是相同實(shí)例)。
裝箱數(shù)字不會(huì)保存它的實(shí)例:
val a: Int = 10000
print(a identityEquals a) // Prints 'true'
val boxedA: Int? = a
val anotherBoxedA: Int? = a
print(boxedA identityEquals 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)換
由于不同的存儲(chǔ)方式小的類型并不是大類型的子類型。
如果它們是的話,就會(huì)出現(xiàn)下述問題(下面的代碼不能通過編譯):
// 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
假設(shè)這樣是可以的,這里我們就悄無聲息的丟掉了一些數(shù)據(jù).
因此較小的類型不能隱式轉(zhuǎn)換為較大的類型。
因此我們不能聲明一個(gè) Byte 類型給一個(gè) Int 變量,在不進(jìn)行顯示轉(zhuǎn)換的情況下。
val b: Byte = 1 // OK, literals are checked statically
val i: Int = b // ERROR
我們可以顯示轉(zhuǎn)換的去擴(kuò)大類型
val i: Int = b.toInt() // OK: explicitly widened
每個(gè)number類型支持如下的轉(zhuǎn)換:
toByte(): BytetoShort(): ShorttoInt(): InttoLong(): LongtoFloat(): FloattoDouble(): DoubletoChar(): Char
失去隱式類型轉(zhuǎn)換,其實(shí)并沒有帶來多少困擾,因?yàn)槭褂米置媪康臅r(shí)候是沒有代價(jià)的,因?yàn)樽置媪康念愋褪峭茖?dǎo)出來的;
另一方面,算數(shù)運(yùn)算操作都針對(duì)不同類型的參數(shù)做好了重載,比如:
val l = 1.toLong() + 3 // Long + Int => Long
運(yùn)算符
Kotlin支持標(biāo)準(zhǔn)的算數(shù)操作符,并在相應(yīng)的類上定義為成員函數(shù)(但編譯器會(huì)針對(duì)運(yùn)算進(jìn)行優(yōu)化,將函數(shù)調(diào)用優(yōu)化成直接的算數(shù)操作)。
查看 Operator overloading.
對(duì)于按位操作(bitwise operation),沒有特別的符號(hào)來表示,而是直接使用命名函數(shù):
val x = (1 shl 2) and 0x000FF000
這是完整的位運(yùn)算操作 (只能對(duì) Int 或者 Long 使用):
-
shl(bits)– signed shift left (Java's<<) -
shr(bits)– signed shift right (Java's>>) -
ushr(bits)– unsigned shift right (Java's>>>) -
and(bits)– bitwise and -
or(bits)– bitwise or -
xor(bits)– bitwise xor -
inv()– bitwise inversion
Characters
Characters 用 Char來表示. 像對(duì)待numbers那樣就行
fun check(c: Char) {
if (c == 1) { // ERROR: incompatible types
// ...
}
}
用單引號(hào)表示一個(gè)Character,例如: '1', '\n', '\uFF00'.
我們可以調(diào)用顯示轉(zhuǎn)換把Character轉(zhuǎn)換為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
}
像numbers, characters是被裝箱當(dāng)使用一個(gè)可空的引用.這樣實(shí)例不會(huì)被保存。
Booleans
類型Boolean有兩個(gè)值: true{: .keyword } 和 false{: .keyword }.
Booleans使用nullable時(shí)候Boolean也會(huì)被裝箱.
內(nèi)置對(duì)Booelan的操作
-
||– 短路或 -
&&– 短路與
數(shù)組
數(shù)組在Kotlin中使用 Array類來表示, Array類定義了set和get函數(shù)(使用時(shí)可以用[],通過符號(hào)重載的約定轉(zhuǎn)換), 和size等等一些有用的成員函數(shù):
class Array<T> private () {
fun size(): Int
fun get(index: Int): T
fun set(index: Int, value: T): Unit
fun iterator(): Iterator<T>
// ...
}
我們可以使用庫函數(shù)array()來創(chuàng)建一個(gè)包含數(shù)值的數(shù)組, array(1, 2, 3) 創(chuàng)建了 array [1, 2, 3].
或者, arrayOfNulls()可以創(chuàng)建一個(gè)指定大小,元素都為空的數(shù)組。
或者使用函數(shù)來創(chuàng)建一個(gè)數(shù)組:
// Creates an Array<String> with values ["0", "1", "4", "9", "16"]
val asc = Array(5, {i -> (i * i).toString()})
綜上, []操作符代表了成員函數(shù)get()和set().
注意: 與Java不同的是, Kotlin中數(shù)組不可變. 這意味著我們不能聲明 Array<String>到Array<Any>, 否則可能會(huì)產(chǎn)生一個(gè)運(yùn)行時(shí)錯(cuò)誤(但是你可以使用 Array<out Any>, 查看 Type Projections).
Kotlin有專門的類來表示原始類型的數(shù)組,避免了裝箱開銷: ByteArray,
ShortArray, IntArray 等等. 這些類和Array并沒有繼承關(guān)系,但是它們有同樣的方法屬性集. 它們也都有相應(yīng)的工廠方法:
val x: IntArray = intArray(1, 2, 3)
x[0] = x[1] + x[2]
字符串
字符串用String表示。字符串是不可變的。
字符串的原始字符可以使用操作符訪問: s[i].
字符串可以使用for{: .keyword }循環(huán)遍歷:
for (c in str) {
println(c)
}
字符串字面量
Kotlin有兩種類型的字符串: 轉(zhuǎn)義字符串可能由轉(zhuǎn)義字符、原生字符串、換行和任意文本.轉(zhuǎn)義字符串很像java的String:
val s = "Hello, world!\n"
轉(zhuǎn)義方式采用傳統(tǒng)的反斜杠.
原生字符串使用三個(gè)引號(hào)(""")包括,內(nèi)部沒有轉(zhuǎn)義,可以包含換行和任何其他文本:
val text = """
for (c in "foo")
print(c)
"""
模板
字符串可以包含模板表達(dá)式,即一些小段代碼,會(huì)求值并把結(jié)果合并到字符串中。模板表達(dá)式以$符號(hào)開始,包含一個(gè)簡(jiǎn)單的名稱:
val i = 10
val s = "i = $i" // evaluates to "i = 10"
或者用花括號(hào)擴(kuò)起來,內(nèi)部可以是任意表達(dá)式:
val s = "abc"
val str = "$s.length is ${s.length}" // evaluates to "abc.length is 3"
Kotlin 開發(fā)者社區(qū)
國(guó)內(nèi)第一Kotlin 開發(fā)者社區(qū)公眾號(hào),主要分享、交流 Kotlin 編程語言、Spring Boot、Android、React.js/Node.js、函數(shù)式編程、編程思想等相關(guān)主題。
