(Kotlin 學習筆記的文檔結構基本按照 Java 核心技術一書的目錄排列)
基本程序設計結構
數據類型
數字
類型 | 寬度 |
---|---|
Double | 64 |
Float | 32 |
Long | 64 |
Int | 32 |
Short | 16 |
Byte | 8 |
Char 類型
Kotlin 中字符類型為 “Char”,和 Java 中不同的是,Kotlin 中的 Char 類型無法作為數字使用。如果需要將 Char 類型轉換為 Int 類型,則可以直接調用"toInt" 方法。
Boolean 類型
Kotlin 中的 Boolean 類型和 Java 中的一樣,只有兩個值true 和 false。
數據類型的表示方式
- 字面常量十進制表示:1234,1234L(Long 類型)
- 十六進制表示:0x1234ABCD
- 二進制表示:0b00100010
- 不存在八進制表示
- Double 類型:123.45,123.45e10
- Float 類型:123.45F/f
- 使用"_"讓數字更加易讀
- 1234_5678_9L
- 0x12_34_56_78_AB
- 0b11010010_01101001_10010100_10010010
變量的初始化
在 Kotlin 中存在有 2 種變量 var 和 val。其中 var 表示的是“通常的變量”,val 則表示的是“不可變變量”,這可以類比 Java 中的 final 修飾的數據類型類型。
一切皆對象,所以不管是var還是val變量,都存在成員函數。而val變量不可變的本質就是它不存在 set 方法。所以,可以使用 var 去覆蓋一個 val ,但是無法反過來為之。
Kotlin 中變量的初始化語句為:
val/var 變量名 : 變量類型 = 值,其中變量類型是可選的
需要注意的是,在 Kotlin 中不允許聲明了一個變量但是卻不去初始化它。
在 Kotlin 中,數據有以下的幾種初始化方法:
val a :Int = 1 // 對變量 a 立即賦值
val b = 2 // 因為很容易推斷出 b 的類型是 Int,所以變量類型可以省略,這種初始化方式后面使用時變量不可賦值為空
val b ?= null // 將 b 的值設置為 null(需要注意 Kotlin 是空類型安全的,每次使用之前需要判斷是否為空)
val c = null!! // 將 b 的值強制設置為 null,則之后的代碼不再做是否為空的安全檢查
b.toLong // 會報錯
c.toLong // 不會報錯
運算符
隱式類型轉換
因為表示的方法不同,較小類型的數據無法隱式轉換為較大類型的數據。也就是說,無法在不同類型之間比較兩個變量是否在“數值”上是否相等。另外,也不可以將較小類型的數據隱式賦值給較大的數據類型:
val a : Int ?= 1
val b : Long ?= 1
print(a == b) // 這里會產生一個錯誤, Int 類型和 Long 類型無法進行比較
/****************************************************************/
val a : Byte = 1
val b : Int = a // 錯誤,小的數據類型無法隱式裝箱為大的數據類型,如果需要賦值應該寫作: = a.toInt()
Boolean 類型的布爾運算
- || :短路邏輯或運算
- &&:短路邏輯與運算
- !:短路邏輯非運算
字符串
在 Kotlin 中字符串使用 String 類型進行表示。字符串是不可變的。字符串默認擁有迭代器,可以使用 foreach 進行遍歷。
和 Java 中的字符串有一處顯然的不同點,那就是 Kotlin 中的字符串除了擁有轉義字符的賦值方式外,還存在類似於 Python 中那種通過三個引號進行的賦值方法,其中被三個引號括起來的所有文字,都是所見即所得的。
val text = """
for (c in "foo")
print(c)
"""
在這種字符串的賦值方式中,還有一種方法,用於去除前導空格。
val text = """
|Tell me and I forget.
|Teach me and I remember.
|Involve me and I learn.
|(Benjamin Franklin)
""".trimMargin()
在上面的例子中,默認使用"|"作為邊界的前綴,如果想要使用其他的符號作為前綴,則將對應符號的字符作為傳輸傳遞入 trimMargin 函數。
字符串模板
Kotlin 的字符串應該吸收了很多腳本語言的字符串處理特性。它可以包含有模板表達式。所謂的模板表達式,你可以將其看作是很短的一小段代碼。模板表達式由 $ 符號開頭,后面緊跟隨一個名稱。這里的名稱可以是某一個變量名。如果需要執行一些比較復雜的表達式,則使用花括號將表達式擴起來共同作為一個名稱。
val strA : String = "abcd"
val strB = "$strA.length is ${s.length}" // abcd.length is 4
流程控制
條件語句
條件語句的形式為:if (condition) statement
。作為擴展,還有 if ... else
語句和多個 if
語句嵌套。
fun max(){
val a = 1
val b = 2
if (a > b) {
retrun a
}else{
return b
}
}
和 Java 中有點不同的是,if
中的分支可以是代碼塊,最后的一個表達式就作為該塊的值。那么,上面的例子就可以寫作:
fun man(){
val a = 1
val b = 2
if (a > b){
a
}else{
b
}
}
另外,if
語句還可以作為表達式使用:
val max = if (a > b) a else b
在上述語句中,變量 max 的值最終是多少,需要看變量 a
和 b
的最終結果。
條件判斷中的范圍判斷
在傳統的 C 語言或者是一些其他的類似 C 的語言中,如果想要判斷一個數是否在一個區間內,可能需要那么寫:
if (i >= 5 && i <= 10) {
// do something
}
而在 Kotlin 中這一切就簡化了許多:
if (i in 5..10) {
// do something
}
另外還有:
if (i !in 5..10) { if (!(i >= 5 && i <= 10))
// do something
}
循環語句
for 循環
需要注意的是,在 Kotlin 中,不支持那種 C 中的傳統 for 循環。
使用迭代器
val items = lostOf("apple","banana","kiwi")
for (item in items) {
println(item)
}
使用索引
val items = lostOf("apple","banana","kiwi")
for (index in items.indices) {
println(${items[index]})
}
雖然不具備類似於 C 中那樣的 for 循環,但是並不意味着 Kotlin 不可以實現那種需求:
for (i in 1..5) { // for (int i = 1;i <= 5;i++) {print(i)}
print(i) // 12345
}
需要注意的是,這里的 1..5
左右都是閉區間的。
for (i in 5..1) {
print(i) // 錯誤,沒有任何輸出
}
類似上面代碼展示的這樣,是無法進行輸出的。如果想要逆序輸出,那么你需要使用函數downTo
替代..
:
for (i in 5 downTo 1) {
print(i) // 54321
}
以上的例子都是針對步長是1的情況,如果實際的步長不是1,那么需要使用 step
函數來指定步長:
for (i in 1..5 step 2) {
print(i) //1 3 5
}
另外,又有一些時候(大部分的時候)可能並不需要包括結束區間。那么,這時候需要使用到 until
函數來替代 ..
:
for (i in 1 until 5) {
print(i) // 1234
}
while 循環
同類 C 語言。
do...while 循環
同類 C 語言。
多重選擇 (when)
Kotlin 中不存在 switch...case...
這樣的表達式,取而代之的是 when
語句。
最簡的 when 語句如下:
when (x) {
1 -> print(1)
2 -> print(2)
else ->print("null")
}
其中的 x 的值將會作為判斷的條件,此 when 語句會逐一比對條件,如果找到任一匹配的條件,則執行->
之后的語句塊然后退出。假如所有的條件都不匹配,則會執行else
對應的語句塊。
和之前的if
語句一樣,when
語句可以作為單獨的表達式使用,也可以作為一個語句使用。如果它作為表達式使用,則對應塊的值會作為此 when 的值,而每一個語句塊的值是由該塊最后一條語句所決定的。另外就是如果作為語句使用,則必須包含有 else
,除非編譯器能夠確定每一個分支都已經覆蓋到了(比如對於 Boolean 類型,則條件應該是 true 和 false,如果已經包含了這 2 個分支,則可以不需要 else。當然,隨手添加一個 else 語句並不是什么壞習慣)。
相對於傳統的類 C 語言,when 語句的條件要寬松很多。除了是一個固定的值,還可以是表達式:
when (x) {
parseInt(s) -> print("s encodes x")
else -> print("s does not encode x")
}
////////////////////////////////////////////
when (x) {
in 1..10 -> print("x is in the range")
in validNumbers -> print("x is valid")
!in 10..20 -> print("x is outside the range")
else -> print("none of the above")
}