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
代码可以运行,但添加两个数字的逻辑位于 result 变量中,这使得您的代码难以重用。相反,您可以将加法运算提取到一个 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
参数,构建指定格式的消息,并返回该消息。
例如,如果函数使用 "Chrome OS
" 作为 operatingSystem
和 "[email protected]
" 作为 emailId
被调用,它应该返回以下字符串
There's a new sign-in request on Chrome OS for your Google Account [email protected].
步骤 1
- 你能在该程序中实现
displayAlertMessage()
函数,使其打印显示的输出吗?
fun main() {
val operatingSystem = "Chrome OS"
val emailId = "[email protected]"
println(displayAlertMessage(operatingSystem, emailId))
}
// Define your displayAlertMessage() below this line.
- 您的程序是否打印以下输出?
There's a new sign-in request on Chrome OS for your Google Account [email protected].
步骤 2
做得很好!您显示了消息。但是,在某些情况下,您发现无法确定用户的操作系统。在这种情况下,您需要将操作系统名称指定为 Unknown OS
。您可以进一步优化代码,以便不必每次调用函数时都传递 Unknown OS
参数。
- 你能找到一种方法,使用此信息来优化代码,使其打印以下输出吗?
There's a new sign-in request on Unknown OS for your Google Account [email protected]. There's a new sign-in request on Windows for your Google Account [email protected]. There's a new sign-in request on Mac OS for your Google Account [email protected].
- 要打印上面的消息,请使用以下代码替换
main()
函数实现
fun main() {
val firstUserEmailId = "[email protected]"
// 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 = "[email protected]"
println(displayAlertMessage(secondUserOperatingSystem, secondUserEmailId))
println()
val thirdUserOperatingSystem = "Mac OS"
val thirdUserEmailId = "[email protected]"
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
- 创建一个
add()
函数,该函数接受一个firstNumber
参数和一个secondNumber
参数,两者都是Int
类型,并返回一个Int
值。 - 在
add()
函数体中输入加法运算的代码,然后使用return
关键字返回运算的结果。
fun add(firstNumber: Int, secondNumber: Int): Int {
return firstNumber + secondNumber
}
步骤 3
- 定义一个
subtract()
函数,该函数接受一个firstNumber
参数和一个secondNumber
参数,两者都是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
- 创建一个
displayAlertMessage()
函数,该函数接受一个operatingSystem
参数和一个emailId
参数,两者都是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
}
比较两个数字
- 创建一个
compareTime()
函数,该函数接受一个timeSpentToday
参数和一个timeSpentYesterday
参数,两者都是Int
类型,并返回一个Boolean
值。
该解决方案依赖于 >
比较运算符。运算符被求值为一个 Boolean
值,因此 compareTime()
函数只是返回 timeSpentToday > timeSpentYesterday
的结果。
例如,如果你将 300
参数传递给 timeSpentToday
参数,并将 250
参数传递给 timeSpentYesterday
参数,则函数体被求值为 300 > 250
,它返回一个 true
值,因为 300 大于 250。
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 核心轨道。要跳转到特定主题,请转到 知识图 以查看轨道中涵盖的主题列表。