這個程式碼研究室是「程式設計人員的 Kotlin 新手上路課程」的一部分。如果您按部就班完成程式碼研究室,就能充分體驗到本課程的價值。視您的知識多寡而定,您或許能略過某些部分。本課程適用於熟悉物件導向語言,且想學習 Kotlin 的程式設計師。
簡介
在本程式碼研究室中,您將學習 Kotlin 程式設計語言的基本概念,包括資料型別、運算子、變數、控制結構,以及可為空值和不可為空值的變數。本課程適用於熟悉物件導向語言,且想學習 Kotlin 的程式設計師。
本課程的設計目標是協助您累積知識,但各單元之間彼此半獨立,因此您可以略過熟悉的部分,不必建構單一範例應用程式。為將這些範例連結在一起,許多範例都使用水族館主題。如要查看完整的魚缸故事,請參閱 Udacity 的程式設計人員 Kotlin 新手上路課程。
必備知識
- 如何在 IntelliJ IDEA 中建立專案
- 如何在 IntelliJ IDEA 中開啟及執行 Kotlin 的 REPL (Read-Eval-Print Loop) 程式碼 (依序點選「Tools」>「Kotlin」>「Kotlin REPL」)
課程內容
- 如何使用 Kotlin 資料類型、運算子和變數
- 如何使用布林值和條件
- 可為空值和不可為空值的變數之間的差異
- Kotlin 中的陣列、清單和迴圈運作方式
學習內容
- 使用 Kotlin REPL 學習 Kotlin 基礎知識
在這項工作中,您將瞭解 Kotlin 程式設計語言中的運算子和型別。
步驟 1:探索數值運算子
- 開啟 IntelliJ IDEA (如果尚未開啟)。
- 如要開啟 Kotlin REPL,請依序選取「Tools」 >「Kotlin」 >「Kotlin REPL」。

與其他語言一樣,Kotlin 使用 +、-、* 和 / 分別代表加、減、乘和除。Kotlin 也支援不同的數字類型,例如 Int、Long、Double 和 Float。
- 在 REPL 中輸入下列運算式。如要查看結果,請在輸入每個運算式後按下
Control+Enter鍵 (在 Mac 上則為Command+Enter鍵)。
1+1 ⇒ res8: kotlin.Int = 2 53-3 ⇒ res9: kotlin.Int = 50 50/10 ⇒ res10: kotlin.Int = 5 1.0/2.0 ⇒ res11: kotlin.Double = 0.5 2.0*3.5 ⇒ res12: kotlin.Double = 7.0
請注意,運算結果會保留運算元的型別,因此 1/2 = 0,但 1.0/2.0 = 0.5。
- 請嘗試使用整數和十進位數字的不同組合來建立運算式。
6*50 ⇒ res13: kotlin.Int = 300 6.0*50.0 ⇒ res14: kotlin.Double = 300.0 6.0*50 ⇒ res15: kotlin.Double = 300.0
- 呼叫數字的一些方法。Kotlin 會將數字保留為基本型別,但您可以在數字上呼叫方法,就像數字是物件一樣。
2.times(3) ⇒ res5: kotlin.Int = 6 3.5.plus(4) ⇒ res8: kotlin.Double = 7.5 2.4.div(2) ⇒ res9: kotlin.Double = 1.2
步驟 2:練習使用型別
Kotlin 不會在數字型別之間隱含轉換,因此您無法將 short 值直接指派給 long 變數,或將 Byte 指派給 Int。這是因為程式中常見的錯誤來源是隱含數字轉換。您隨時可以透過轉換類型指派不同類型的值。
- 如要查看一些可能的轉換,請在 REPL 中定義
Int類型的變數。
val i: Int = 6- 建立新變數,然後輸入上述變數名稱,後面加上
.to。
val b1 = i.toIntelliJ IDEA 會顯示可能的完成項目清單。這項自動完成功能適用於任何型別的變數和物件。
- 從清單中選取
toByte(),然後列印變數。
val b1 = i.toByte()
println(b1)⇒ 6
- 為不同類型的變數指派
Byte值。
val b2: Byte = 1 // OK, literals are checked statically
println(b2)
⇒ 1
val i1: Int = b2
⇒ error: type mismatch: inferred type is Byte but Int was expected
val i2: String = b2
⇒ error: type mismatch: inferred type is Byte but String was expected
val i3: Double = b2
⇒ error: type mismatch: inferred type is Byte but Double was expected- 如果作業傳回錯誤,請改為投放到電視。
val i4: Int = b2.toInt() // OK!
println(i4)
⇒ 1
val i5: String = b2.toString()
println(i5)
⇒ 1
val i6: Double = b2.toDouble()
println(i6)
⇒ 1.0- 為了讓長數字常數更易讀,Kotlin 允許您在數字中加入底線,方便您閱讀。請嘗試輸入其他數值常數。
val oneMillion = 1_000_000 val socialSecurityNumber = 999_99_9999L val hexBytes = 0xFF_EC_DE_5E val bytes = 0b11010010_01101001_10010100_10010010
步驟 3:瞭解變數類型的值
Kotlin 支援兩種類型的變數:可變更和不可變更。使用 val 時,您可以指派值一次。如果您嘗試重新指派其他值,就會收到錯誤訊息。使用 var 時,您可以指派值,之後也能透過程式變更該值。
- 使用
val和var定義變數,然後為變數指派新值。
var fish = 1
fish = 2
val aquarium = 1
aquarium = 2⇒ error: val cannot be reassigned
您可以為 fish 指派值,然後指派新值,因為這是以 var 定義。嘗試為 aquarium 指派新值會產生錯誤,因為該值是以 val 定義。
當編譯器可從內容判斷類型時,系統會推斷您儲存在變數中的類型。您隨時可以使用半形冒號標記法,明確指定變數的型別。
- 定義一些變數,並明確指定型別。
var fish: Int = 12
var lakes: Double = 2.5一旦您或編譯器指派了型別,就無法變更型別,否則會發生錯誤。
步驟 4:瞭解字串
Kotlin 中的字串與其他程式設計語言中的字串非常相似,使用 " 表示字串,使用 ' 表示單一字元,並可使用 + 運算子串連字串。您可以將字串範本與值合併來建立字串範本;$variable 名稱會替換為代表該值的文字。這就是所謂的「變數插補」。
- 建立字串範本。
val numberOfFish = 5
val numberOfPlants = 12
"I have $numberOfFish fish" + " and $numberOfPlants plants"⇒ res20: kotlin.String = I have 5 fish and 12 plants
- 建立含有運算式的字串範本。如同其他語言,值可以是運算式的結果。使用大括號
{}定義運算式。
"I have ${numberOfFish + numberOfPlants} fish and plants"⇒ res21: kotlin.String = I have 17 fish and plants
在這項工作中,您將瞭解 Kotlin 程式設計語言中的布林值和檢查條件。與其他語言一樣,Kotlin 也有布林值和布林運算子,例如小於、等於、大於等等 (<、==、>、!=、<=、>=)。
- 編寫
if/else陳述式。
val numberOfFish = 50
val numberOfPlants = 23
if (numberOfFish > numberOfPlants) {
println("Good ratio!")
} else {
println("Unhealthy ratio")
}⇒ Good ratio!
- 請嘗試在
if陳述式中使用範圍。在 Kotlin 中,您測試的條件也可以使用範圍。
val fish = 50
if (fish in 1..100) {
println(fish)
}⇒ 50
- 撰寫包含多個案例的
if。如需更複雜的條件,請使用邏輯 AND&&和邏輯 OR||。與其他語言一樣,您可以使用else if建立多個案例。
if (numberOfFish == 0) {
println("Empty tank")
} else if (numberOfFish < 40) {
println("Got fish!")
} else {
println("That's a lot of fish!")
}⇒ That's a lot of fish!
- 試試
when陳述式。在 Kotlin 中,您可以使用when陳述式,以更簡潔的方式編寫一系列if/else if/else陳述式,這類似於其他語言中的switch陳述式。when陳述式中的條件也可以使用範圍。
when (numberOfFish) {
0 -> println("Empty tank")
in 1..39 -> println("Got fish!")
else -> println("That's a lot of fish!")
}⇒ That's a lot of fish!
在這項工作中,您將瞭解可為空值與不可為空值的變數。無關的程式設計錯誤是無數錯誤的根源。Kotlin 導入不可為空值的變數,以減少錯誤。
步驟 1:瞭解可空值性
根據預設,變數不能為 null。
- 宣告
Int並將null指派給該項目。
var rocks: Int = null⇒ error: null can not be a value of a non-null type Int
- 在型別後方使用問號運算子
?,表示變數可為空值。宣告Int?並將null指派給該項目。
var marbles: Int? = null如果資料類型較為複雜 (例如清單):
- 您可以允許清單的元素為空值。
- 您可以允許清單為空值,但如果清單不是空值,則其元素不得為空值。
- 您可以允許清單或元素為空值。
清單和其他複雜資料類型會在後續工作中介紹。
步驟 2:瞭解「?」和 ?: 運算子
您可以使用 ? 運算子測試 null,省去編寫許多 if/else 陳述式的麻煩。
- 以較長的方式編寫程式碼,檢查
fishFoodTreats變數是否不是null。然後遞減該變數。
var fishFoodTreats = 6
if (fishFoodTreats != null) {
fishFoodTreats = fishFoodTreats.dec()
}- 現在來看看如何使用
?運算子,以 Kotlin 方式編寫。
var fishFoodTreats = 6
fishFoodTreats = fishFoodTreats?.dec()- 您也可以使用
?:運算子串連空值測試。請參閱以下範例:
fishFoodTreats = fishFoodTreats?.dec() ?: 0這是簡寫,代表「如果 fishFoodTreats 不是 null,則遞減並使用該值;否則使用 ?: 後的值,也就是 0」。如果 fishFoodTreats 為 null,系統會停止評估,且不會呼叫 dec() 方法。
空值指標的相關重點
如果您真的很喜歡 NullPointerExceptions,Kotlin 可讓您保留這些項目。非空值斷言運算子 !! (雙驚嘆號) 會將任何值轉換為非空值型別,如果值為 null,則會擲回例外狀況。
val len = s!!.length // throws NullPointerException if s is null在這項工作中,您將瞭解陣列和清單,以及在 Kotlin 程式設計語言中建立迴圈的不同方式。
步驟 1:製作清單
清單是 Kotlin 中的基本型別,與其他語言中的清單類似。
- 使用
listOf宣告清單並列印出來。這份清單無法變更。
val school = listOf("mackerel", "trout", "halibut")
println(school)⇒ [mackerel, trout, halibut]
- 使用
mutableListOf宣告可變更的清單。移除項目。
val myList = mutableListOf("tuna", "salmon", "shark")
myList.remove("shark")⇒ res36: kotlin.Boolean = true
如果 remove() 方法成功移除傳遞的項目,就會傳回 true。
步驟 2:建立陣列
與其他語言一樣,Kotlin 也有陣列。與 Kotlin 中的清單不同 (有可變動和不可變動版本),Array 沒有可變動版本。建立陣列後,大小就會固定。您無法新增或移除元素,但可以複製到新陣列。
使用 val 和 var 的規則與陣列和清單相同。
- 使用
arrayOf宣告字串陣列。使用java.util.Arrays.toString()陣列公用程式列印出來。
val school = arrayOf("shark", "salmon", "minnow")
println(java.util.Arrays.toString(school))⇒ [shark, salmon, minnow]
- 以
arrayOf宣告的陣列不會與元素相關聯,因此您可以混合類型,這很有幫助。宣告具有不同型別的陣列。
val mix = arrayOf("fish", 2)- 您也可以為所有元素宣告單一類型的陣列。使用
intArrayOf()宣告整數陣列。其他型別的陣列也有對應的建構工具或例項函式。
val numbers = intArrayOf(1,2,3)- 使用
+運算子合併兩個陣列。
val numbers = intArrayOf(1,2,3)
val numbers3 = intArrayOf(4,5,6)
val foo2 = numbers3 + numbers
println(foo2[5])=> 3
- 嘗試不同的巢狀陣列和清單組合。與其他語言一樣,您可以巢狀方式使用陣列和清單。也就是說,當您將陣列放入陣列中時,會得到陣列的陣列,而不是兩個陣列內容的扁平化陣列。陣列的元素也可以是清單,清單的元素也可以是陣列。
val numbers = intArrayOf(1, 2, 3)
val oceans = listOf("Atlantic", "Pacific")
val oddList = listOf(numbers, oceans, "salmon")
println(oddList)⇒ [[I@89178b4, [Atlantic, Pacific], salmon]
第一個元素 numbers 是 Array。如果您未使用陣列公用程式列印陣列,Kotlin 會列印位址,而不是陣列內容。
- Kotlin 的一項優點是,您可以使用程式碼初始化陣列,不必將陣列初始化為 0。請試試這個例句:
val array = Array (5) { it * 2 }
println(java.util.Arrays.toString(array))⇒ [0, 2, 4, 6, 8]
初始化程式碼位於大括號之間,即 {}。在程式碼中,it 是指陣列索引,從 0 開始。
步驟 3:製作循環
現在您已擁有清單和陣列,可以按照預期方式逐一處理元素。
- 建立陣列。使用
for迴圈疊代陣列並列印元素。
val school = arrayOf("shark", "salmon", "minnow")
for (element in school) {
print(element + " ")
}⇒ shark salmon minnow
- 在 Kotlin 中,您可以同時對元素和索引進行迴圈。請試試這個例句:
for ((index, element) in school.withIndex()) {
println("Item at $index is $element\n")
}⇒ Item at 0 is shark Item at 1 is salmon Item at 2 is minnow
- 請嘗試不同的步幅和範圍。您可以指定數字或字元的範圍 (依字母順序)。與其他語言一樣,您不必以 1 為步進值。你可以使用
downTo倒轉。
for (i in 1..5) print(i)
⇒ 12345
for (i in 5 downTo 1) print(i)
⇒ 54321
for (i in 3..6 step 2) print(i)
⇒ 35
for (i in 'd'..'g') print (i)
⇒ defg- 試用幾個迴圈。與其他語言一樣,Kotlin 也有
while迴圈、do...while迴圈,以及++和--運算子。Kotlin 也有repeat迴圈。
var bubbles = 0
while (bubbles < 50) {
bubbles++
}
println("$bubbles bubbles in the water\n")
do {
bubbles--
} while (bubbles > 50)
println("$bubbles bubbles in the water\n")
repeat(2) {
println("A fish is swimming")
}⇒ 50 bubbles in the water 49 bubbles in the water A fish is swimmingA fish is swimming
在運算子、清單和迴圈等基本概念方面,Kotlin 與其他語言非常相似,但仍有一些重要差異。
Kotlin 的下列功能可能與其他語言不同:
- Kotlin 型別無法隱含轉換,請使用轉型。
- 使用
val宣告的變數只能指派一次。 - 根據預設,Kotlin 變數不可為空值。使用
?將變數設為可為空值。 - 使用 Kotlin 時,您可以在
for迴圈中同時遍歷陣列的索引和元素。
下列 Kotlin 程式設計建構函式與其他語言中的建構函式類似:
- 陣列和清單可以包含單一類型或混合類型。
- 陣列和清單可以巢狀結構呈現。
- 您可以使用
for、while、do/while和repeat建立迴圈。 when陳述式是 Kotlin 版本的switch陳述式,但when更具彈性。
Kotlin 說明文件
如要進一步瞭解本課程的任何主題,或遇到問題,請前往 https://kotlinlang.org。
Kotlin 教學課程
https://try.kotlinlang.org 網站提供豐富的教學課程 (稱為 Kotlin Koans)、網頁式解譯器,以及附有範例的完整參考文件。
Udacity 課程
如要查看這個主題的 Udacity 課程,請參閱「程式設計人員的 Kotlin 新手上路課程」。
IntelliJ IDEA
IntelliJ IDEA 的說明文件位於 JetBrains 網站。
本節列出的作業可由課程講師指派給學習本程式碼研究室的學員。講師可自由採取以下行動:
- 視需要指派作業。
- 告知學員如何繳交作業。
- 為作業評分。
講師可以視需求使用全部或部分建議內容,也可以自由指派任何其他合適的作業。
如果您是自行學習本程式碼研究室,不妨利用這些作業驗收學習成果。
回答問題
第 1 題
下列哪一項會宣告不可變更的字串清單?
▢ val school = arrayOf("shark", "salmon", "minnow")
▢ var school = arrayOf("shark", "salmon", "minnow")
▢ val school = listOf("shark", "salmon", "minnow")
▢ val school = mutableListOf("shark", "salmon", "minnow")
第 2 題
下列程式碼的輸出內容為何?for (i in 3..8 step 2) print(i)
▢ 345678
▢ 468
▢ 38
▢ 357
第 3 題
這個程式碼中的問號用途為何?var rocks: Int? = 3
▢ 變數 rocks 的類型不固定。
▢ 變數 rocks 可以設為空值。
▢ 變數 rocks 不得設為空值。
▢ 變數 rocks 不應立即初始化。
繼續下一個課程:
如要查看課程總覽,包括其他程式碼研究室的連結,請參閱「程式設計人員的 Kotlin 新手上路課程:歡迎參加本課程。」