1. 事前準備
您已花了很多心力瞭解 Kotlin 程式設計的基本知識,現在是時候來實際運用所學了。
這些練習可測試您對於所學概念的理解程度。主題是根據實際用途而定,其中有些您或許已經看過。
按照操作說明找出每個問題的解決方案。如果遇到困難,其中一些練習可以給予提示。雖然解決方案程式碼就在這個練習的結尾處,但我們極力建議您先解決練習中的問題,再查看答案。
不妨將解決方案視為一種解決問題的方法,您也可以盡情地進行實驗。您可以運用多種方式來解決某些練習,並為函式和變數使用不同的名稱。
請依照自己的步調逐一瞭解問題所在。我們提供的預估時間僅供參考,您不必一定要在時間內完成。建議您花些時間仔細思考每個問題的解決方法。
建議使用 Kotlin Playground 來解決這些練習的問題。
必要條件
- 熟悉 Kotlin Playground
- 具備定義及呼叫函式的能力
- 具備 Kotlin 基本資料類型的知識
- 具備不可變動和可變動變數的知識
- 具備
println()
函式的知識 - 完成下列程式碼研究室:您在 Kotlin 中的第一個程式、在 Kotlin 中建立及使用變數,以及在 Kotlin 中建立及使用函式
軟硬體需求
- 一台可連上網際網路並具備網路瀏覽器的電腦
2. 輸出訊息
和朋友分享在這個課程中學到的知識。
- 您是否能撰寫可分別以四行輸出這些訊息的
main()
函式?
Use the val keyword when the value doesn't change. Use the var keyword when the value can change. When you define a function, you define the parameters that can be passed to it. When you call a function, you pass arguments for the parameters.
3. 修正編譯錯誤
這個程式會輸出訊息,通知使用者已收到朋友傳送的即時通訊訊息。
fun main() {
println("New chat message from a friend'}
}
- 您能找出這個程式中編譯錯誤的根本原因並加以修正嗎?
- 程式碼是否使用適當符號,來表示字串和函式引數的開始和結束?
提示:您可以使用 Kotlin Playground 執行程式碼,並查看編譯錯誤。
修正錯誤後,程式應該可以在沒有錯誤的情況下編譯,且可以將以下內容輸出:
New chat message from a friend
4. 字串範本
這個程式會通知使用者特定商品即將推出的促銷活動。其中包含字串範本,這個範本分別使用 discountPercentage
和 item
變數來表示折扣百分比和特價商品,但程式碼中含有編譯錯誤。
fun main() {
val discountPercentage: Int = 0
val offer: String = ""
val item = "Google Chromecast"
discountPercentage = 20
offer = "Sale - Up to $discountPercentage% discount on $item! Hurry up!"
println(offer)
}
- 您能找出錯誤的根本原因並加以修正嗎?
- 在 Kotlin Playground 中執行程式碼前,您能否決定這個程式的輸出內容?
提示:您能否將值重新指派給唯讀變數?
修正錯誤後,程式應該可以在沒有錯誤的情況下編譯,且可以將以下內容輸出:
Sale - Up to 20% discount on Google Chromecast! Hurry up!
5. 字串串連
這個程式會顯示派對總人數。派對中有成人和兒童。numberOfAdults
變數代表派對的成人人數,numberOfKids
變數則代表兒童人數。
fun main() {
val numberOfAdults = "20"
val numberOfKids = "30"
val total = numberOfAdults + numberOfKids
println("The total party size is: $total")
}
步驟 1
- 在 Kotlin Playground 中執行程式碼前,您能否決定這個程式的輸出內容?
決定輸出內容之後,請在 Kotlin Playground 中執行程式碼,然後檢查輸出內容是否與所顯示的相符。
提示:在兩個字串中使用 +
運算子會有什麼影響?
步驟 2
程式碼可以執行及輸出部分內容,但輸出內容不會顯示參加派對的總人數。
- 您是否能找出程式碼中的問題並加以修正,使程式碼可以輸出此內容?
The total party size is: 50
6. 訊息格式
這個程式會顯示員工本月獲得的總薪酬。總薪酬可分為兩個部分:baseSalary
變數 (員工每月收到的薪酬) 和 bonusAmount
變數 (員工可獲得的額外獎勵)。
fun main() {
val baseSalary = 5000
val bonusAmount = 1000
val totalSalary = "$baseSalary + $bonusAmount"
println("Congratulations for your bonus! You will receive a total of $totalSalary (additional bonus).")
}
- 您是否能在 Kotlin Playground 中執行程式碼前,釐清這個程式碼的輸出內容?
- 在 Kotlin Playground 中執行程式碼時,程式碼是否如預期輸出內容?
7. 實作基本數學運算
在本練習中,您會編寫一個程式來執行基本數學運算並將內容輸出。
步驟 1
這個 main()
函式有一個編譯錯誤:
fun main() {
val firstNumber = 10
val secondNumber = 5
println("$firstNumber + $secondNumber = $result")
}
- 您能否修正錯誤,讓程式輸出這個內容?
10 + 5 = 15
步驟 2
程式碼雖然正常運作,但新增兩個數字的邏輯位於結果變數中,因而使得程式碼較無法靈活重複使用。您可以改為將加總運算擷取至 add()
函式中,如此一來就能重複使用該程式碼。如要執行這項操作,請使用下列程式碼來更新程式碼。請注意,程式碼現在會實作名為 thirdNumber
的新 val
,並以 firstNumber
輸出這個新變數的結果。
fun main() {
val firstNumber = 10
val secondNumber = 5
val thirdNumber = 8
val result = add(firstNumber, secondNumber)
val anotherResult = add(firstNumber, thirdNumber)
println("$firstNumber + $secondNumber = $result")
println("$firstNumber + $thirdNumber = $anotherResult")
}
// Define add() function below this line
- 您是否能定義
add()
函式,讓程式能將此內容輸出?
10 + 5 = 15 10 + 8 = 18
步驟 3
現在,您擁有可重複使用的函式可新增兩個數字。
- 您是否能以實作
add()
函式的方式實作subtract()
函式?請一併修改main()
函式來使用subtract()
函式,這樣您就能確認這個函式是否可正常運作。
提示:請考量加減和其他數學運算之間的差異。開始在這裡運用解決方案程式碼。
8. 預設參數
Gmail 提供一項功能,可於每次有人嘗試在新裝置上登入時,傳送通知給使用者。
在本練習中,您會撰寫一個程式,透過這個訊息範本向使用者顯示訊息:
There's a new sign-in request on operatingSystem for your Google Account emailId.
您必須實作接受 operatingSystem
參數和 emailId
參數的函式,以特定格式建構訊息,然後傳回訊息。
例如,如果為 operatingSystem
使用「Chrome OS
」呼叫函式,並為 emailId
使用「sample@gmail.com
」呼叫,系統應該會傳回下列字串:
There's a new sign-in request on Chrome OS for your Google Account sample@gmail.com.
步驟 1
- 您是否能在這個程式中實作
displayAlertMessage()
函式,藉此輸出顯示的內容?
fun main() {
val operatingSystem = "Chrome OS"
val emailId = "sample@gmail.com"
println(displayAlertMessage(operatingSystem, emailId))
}
// Define your displayAlertMessage() below this line.
- 程式是否會輸出這個內容?
There's a new sign-in request on Chrome OS for your Google Account sample@gmail.com.
步驟 2
做得好!您已顯示了這個訊息。然而在某些情況下,您可能會發現自己無法判定使用者的作業系統。此時,必須將作業系統名稱指定為 Unknown OS
。您可以進一步將程式碼最佳化,這樣就不需要每次在呼叫函式時傳遞 Unknown OS
引數。
- 您是否能找到方法運用這項資訊將程式碼最佳化,以便輸出這項內容?
There's a new sign-in request on Unknown OS for your Google Account user_one@gmail.com. There's a new sign-in request on Windows for your Google Account user_two@gmail.com. There's a new sign-in request on Mac OS for your Google Account user_three@gmail.com.
- 如要輸出上述訊息,請使用下列項目取代
main()
函式實作:
fun main() {
val firstUserEmailId = "user_one@gmail.com"
// The following line of code assumes that you named your parameter as emailId.
// If you named it differently, feel free to update the name.
println(displayAlertMessage(emailId = firstUserEmailId))
println()
val secondUserOperatingSystem = "Windows"
val secondUserEmailId = "user_two@gmail.com"
println(displayAlertMessage(secondUserOperatingSystem, secondUserEmailId))
println()
val thirdUserOperatingSystem = "Mac OS"
val thirdUserEmailId = "user_three@gmail.com"
println(displayAlertMessage(thirdUserOperatingSystem, thirdUserEmailId))
println()
}
9. 計步器
計步器是一種可計算步數的電子裝置。如今,幾乎所有手機、智慧型手錶和健身器材都有內建計步器。健康與健身應用程式會使用內建計步器來計算步數。這個函式會根據使用者的步數計算其消耗的卡路里數。
- 您是否能根據最佳做法,重新命名這個程式中的函式、函式參數和變數?
fun main() {
val Steps = 4000
val caloriesBurned = PEDOMETERstepsTOcalories(Steps);
println("Walking $Steps steps burns $caloriesBurned calories")
}
fun PEDOMETERstepsTOcalories(NumberOFStepS: Int): Double {
val CaloriesBURNEDforEachStep = 0.04
val TotalCALORIESburned = NumberOFStepS * CaloriesBURNEDforEachStep
return TotalCALORIESburned
}
10. 比較兩個數字
現代手機內建一項功能,可追蹤裝置使用時間或每日手機使用時間。
在這項練習中,您會實作一個函式,以分鐘來比較自己今天和昨天使用手機的時間。這個函式接受兩個整數參數,並傳回布林值。
第一個參數會顯示您今天所花費的分鐘數,第二個參數則顯示您昨天所花費的分鐘數。如果與昨天相比,您在手機上花費更多時間,則該函式會傳回 true
值。否則,則會傳回 false
值。
舉例來說,如果使用下列具名引數呼叫函式:
timeSpentToday = 300
和timeSpentYesterday = 250
,函式會傳回true
值。timeSpentToday = 300
和timeSpentYesterday = 300
,函式會傳回false
值。timeSpentToday = 200
和timeSpentYesterday = 220
,函式會傳回false
值。
提示:如果運算子之前的值大於之後的值,則 >
比較運算子會傳回 true
值。否則,則會傳回 false
值。
11. 將重複的程式碼移到函式中
這個程式會顯示不同城市的天氣資訊。包括城市名稱、當天的高溫和低溫,以及降雨機率。
fun main() {
println("City: Ankara")
println("Low temperature: 27, High temperature: 31")
println("Chance of rain: 82%")
println()
println("City: Tokyo")
println("Low temperature: 32, High temperature: 36")
println("Chance of rain: 10%")
println()
println("City: Cape Town")
println("Low temperature: 59, High temperature: 64")
println("Chance of rain: 2%")
println()
println("City: Guatemala City")
println("Low temperature: 50, High temperature: 55")
println("Chance of rain: 7%")
println()
}
程式碼有許多相似之處,可針對每個城市輸出天氣資訊。例如有些詞組會重複出現,像是 "City:"
和 "Low temperature:"
。同樣地,重複的程式碼也會造成程式出現錯誤的風險。可能其中一個城市有拼寫錯誤,或是您遺漏了其中一筆天氣的詳細資料。
- 您是否能建立函式來輸出單一城市的天氣詳細資料,以便減少
main()
函式中的重複情形,並對其餘城市重複上述步驟? - 您是否能更新
main()
函式,來呼叫您為每個城市所建立的函式,並傳遞適當的天氣詳細資料做為引數?
12. 解決方案程式碼
輸出訊息
這項解決方案會使用 println()
函式輸出每一行的訊息。
fun main() {
println("Use the val keyword when the value doesn't change.")
println("Use the var keyword when the value can change.")
println("When you define a function, you define the parameters that can be passed to it.")
println("When you call a function, you pass arguments for the parameters.")
}
修正編譯錯誤
這個程式碼含有兩個編譯錯誤:
- 字串結尾應為雙引號,而非單引號。
- 函式引數應以括號而非以大括號結尾。
fun main() {
println("New chat message from a friend")
}
字串範本
編譯錯誤是將 discountPercentage
和 offer
唯讀變數指派至新值所產生的結果,而系統不允許這項指派作業。
fun main() {
val discountPercentage = 20
val item = "Google Chromecast"
val offer = "Sale - Up to $discountPercentage% discount off $item! Hurry Up!"
println(offer)
}
替代的解決方式是使用 var
關鍵字宣告 discountPercentage
整數和 offer
字串。不過在這個程式中,其值是不可變動的,因此可以繼續使用 val
關鍵字。
字串串連
步驟 1
程式會輸出以下內容:
The total party size is: 2030
這是陷阱題。在 String
值上使用 +
運算子時,系統會產生串連字串。由於整數是以雙引號括住,因此系統會將其視為字串,而非整數,因此輸出 2030
的結果。
步驟 2
您可以移除 numberOfAdults
和 numberOfKids
變數前後的雙引號,來將其轉換為 Int
變數。
fun main() {
val numberOfAdults = 20
val numberOfKids = 30
val total = numberOfAdults + numberOfKids
println("The total party size is: $total")
}
假如您記得,Kotlin 編譯器可根據指派的值來推斷變數類型。在這個範例中,編譯器推斷 numberOfAdults
和 numberOfKids
變數為 Int
類型。
訊息格式
程式會輸出以下內容:
Congratulations for your bonus! You will receive a total of 5000 + 1000 (additional bonus).
"$baseSalary + $bonusAmount"
使用範本運算式語法。在範本運算式中,系統會先評估程式碼,然後再將結果在字串中串連。
在這個問題中,$baseSalary
變數經評估為 5000
值,而 $bonusAmount
變數經評估為 1000
值。接著,系統會串連結果以產生 "5000 + 1000"
,並將結果指派給 result
變數。
實作基本數學運算
步驟 1
使用 val
關鍵字定義不可變動的 result
變數,然後為其指派加總運算的結果:
fun main() {
val firstNumber = 10
val secondNumber = 5
val result = firstNumber + secondNumber
println("$firstNumber + $secondNumber = $result")
}
步驟 2
- 建立可接受
firstNumber
和secondNumber
參數的add()
函式,兩者皆為Int
類型,接著傳回Int
值。 - 在
add()
函式主體中輸入加總運算的程式碼,接著使用return
關鍵字傳回運算結果。
fun add(firstNumber: Int, secondNumber: Int): Int {
return firstNumber + secondNumber
}
步驟 3
- 定義接受
firstNumber
和secondNumber
參數的subtract()
函式,兩者皆為Int
類型並傳回Int
值。 - 在
subtract()
函式主體中輸入減法運算的程式碼,接著使用return
關鍵字傳回運算結果。
fun subtract(firstNumber: Int, secondNumber: Int): Int {
return firstNumber - secondNumber
}
- 修改
main()
函式即可使用新的subtract()
函式。解決方案範例如下:
fun main() {
val firstNumber = 10
val secondNumber = 5
val thirdNumber = 8
val result = add(firstNumber, secondNumber)
val anotherResult = subtract(firstNumber, thirdNumber)
println("$firstNumber + $secondNumber = $result")
println("$firstNumber - $thirdNumber = $anotherResult")
}
fun add(firstNumber: Int, secondNumber: Int): Int {
return firstNumber + secondNumber
}
fun subtract(firstNumber: Int, secondNumber: Int): Int {
return firstNumber - secondNumber
}
預設參數
步驟 1
- 建立可接受
operatingSystem
和emailId
參數的displayAlertMessage()
函式,兩者皆為String
類型,接著傳回String
值。 - 在函式主體中,使用範本運算式更新訊息並將其傳回。
fun displayAlertMessage(operatingSystem: String, emailId: String): String {
return "There is a new sign-in request on $operatingSystem for your Google Account $emailId."
}
步驟 2
- 將
"Unknown OS"
值指派給operatingSystem
參數。
fun displayAlertMessage(
operatingSystem: String = "Unknown OS",
emailId: String
): String {
return "There is a new sign-in request on $operatingSystem for your Google Account $emailId."
}
計步器
函式名稱和變數名稱應遵循「駝峰式大小寫」慣例。
如果名稱包含多個字詞,第一個字詞的首字母請使用小寫、其餘字詞的首字母則使用大寫,字詞之間的所有空格也要移除。
範例函式名稱包含:
calculateTip
displayMessage
takePhoto
範例變數名稱包含:
numberOfEmails
cityName
bookPublicationDate
如要進一步瞭解名稱,請參閱命名規則。
請避免使用 Kotlin 關鍵字做為函式名稱,因為這些字詞已在 Kotlin 語言中被賦予具體意義。
您的解決方案程式碼看起來應該會類似以下的程式碼片段:
fun main() {
val steps = 4000
val caloriesBurned = pedometerStepsToCalories(steps);
println("Walking $steps steps burns $caloriesBurned calories")
}
fun pedometerStepsToCalories(numberOfSteps: Int): Double {
val caloriesBurnedForEachStep = 0.04
val totalCaloriesBurned = numberOfSteps * caloriesBurnedForEachStep
return totalCaloriesBurned
}
比較兩個數字
- 建立可接受
timeSpentToday
和timeSpentYesterday
參數的compareTime()
函式,兩者皆為Int
類型,接著傳回Boolean
值。
這項解決方案會使用 >
比較運算子。運算子會評估 Boolean
值,因此 compareTime()
函式只會傳回 timeSpentToday > timeSpentYesterday
的結果。
舉例來說,如果將 300
引數傳遞至 timeSpentToday
參數,並將 250
引數傳遞至 timeSpentYesterday
參數,那麼函式主體會評估 300 > 250
,因為 300 大於 250,所以會傳回 true
。
fun main() {
println("Have I spent more time using my phone today: ${compareTime(300, 250)}")
println("Have I spent more time using my phone today: ${compareTime(300, 300)}")
println("Have I spent more time using my phone today: ${compareTime(200, 220)}")
}
fun compareTime(timeSpentToday: Int, timeSpentYesterday: Int): Boolean {
return timeSpentToday > timeSpentYesterday
}
Have I spent more time using my phone today: true Have I spent more time using my phone today: false Have I spent more time using my phone today: false
將重複的程式碼移到函式中
- 建立可在
main()
函式後輸出安卡拉城的天氣詳細資料的函式。
針對函式名稱,您可以使用 printWeatherForCity()
或類似的程式碼。
- 在
main()
函式中呼叫該函式。
這個程式應輸出安卡拉的天氣詳細資料。
fun main() {
printWeatherForCity()
}
fun printWeatherForCity() {
println("City: Ankara")
println("Low temperature: 27, High temperature: 31")
println("Chance of rain: 82%")
println()
}
您現在可以建立更為彈性的函式,方便輸出其他城市的天氣詳細資料。
- 將
println()
陳述式的安卡拉特定部分替代為變數。
記得遵循慣例,在變數之前為變數名稱和 $
符號使用駝峰式大小寫,這樣系統才會使用變數值而非變數名稱。這些是您在先前的程式碼研究室中學到的字串範本。
fun printWeatherForCity() {
println("City: $cityName")
println("Low temperature: $lowTemp, High temperature: $highTemp")
println("Chance of rain: $chanceOfRain%")
println()
}
- 變更函式定義,讓這些變數成為呼叫時必須傳遞至函式的參數,並為每個參數指定資料類型。
cityName
參數為 String
類型,lowTemp
、highTemp
和 chanceOfRain
參數則為 Int
類型。
由於訊息會輸出至輸出內容,因此函式中不需要使用 return
值。
fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
println("City: $cityName")
println("Low temperature: $lowTemp, High temperature: $highTemp")
println("Chance of rain: $chanceOfRain%")
println()
}
- 更新
main()
函式以呼叫printWeatherForCity()
函式,並傳遞安卡拉的天氣詳細資料。
城市名稱為 "Ankara"
,低溫為27
,高溫為 31
,降雨機率為 82
。
fun main() {
printWeatherForCity("Ankara", 27, 31, 82)
}
fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
println("City: $cityName")
println("Low temperature: $lowTemp, High temperature: $highTemp")
println("Chance of rain: $chanceOfRain%")
println()
}
- 執行程式以確認輸出內容會顯示安卡拉的天氣詳細資料。
- 呼叫
printWeatherForCity()
函式,其中含有其他城市的天氣詳細資料。
fun main() {
printWeatherForCity("Ankara", 27, 31, 82)
printWeatherForCity("Tokyo", 32, 36, 10)
printWeatherForCity("Cape Town", 59, 64, 2)
printWeatherForCity("Guatemala City", 50, 55, 7)
}
fun printWeatherForCity(cityName: String, lowTemp: Int, highTemp: Int, chanceOfRain: Int) {
println("City: $cityName")
println("Low temperature: $lowTemp, High temperature: $highTemp")
println("Chance of rain: $chanceOfRain%")
println()
}
- 執行程式。
雖然輸出內容應該與原先的程式相同,但現在程式碼變得更簡潔,且沒有不必要的重複!用於輸出城市天氣詳細資料的所有程式碼全部集中於一處:printWeatherForCity()
函式。如要變更天氣詳細資料的顯示方式,只要在單一位置進行變更,系統就會套用至所有城市。
13. 其他練習
如果想取得更多有關 Kotlin 語言的練習內容,請查看 JetBrains Academy 的 Kotlin 基本概念課程。如要跳到特定主題,請前往知識地圖,瀏覽課程所涵蓋主題的清單。