在 Kotlin 中创建生日祝福语

1. 简介

在此 Codelab 中,您将创建一个简短的 Kotlin 程序,用于输出包含蛋糕图形和生日横幅的生日祝福语。

前提条件

学习内容

  • 如何通过您的程序输出更复杂的文本。
  • 如何在 Kotlin 中进行基本的数学运算并将结果存储在变量中以备后用。
  • 如何创建函数来多次输出同一个字符串。
  • 如何创建循环来多次输出一个文本片段。

构建内容

  • 您将创建一个简短的程序,用于输出生日祝福语、基于文本的蛋糕图形和横幅。

所需条件

  • 可连接到互联网的计算机和新版网络浏览器(例如最新版 Chrome)。

2. 在 Kotlin 中创建生日祝福语

设置起始代码

  1. 在浏览器中,打开 https://developer.android.com/training/kotlinplayground。这将打开一个基于浏览器的 Kotlin 编程工具。
  2. 在 fun main() 函数内,将 "Hello, world!" 文本替换为 "Happy Birthday, Rover!"。
  3. 在这行文本下方(仍在大括号内),再添加两行要输出的文本:"You are already 5!" 和 "5 is the very best age to celebrate!".

完成后的代码应如下所示。

fun main() {
    println("Happy Birthday, Rover!")
    println("You are already 5!")
    println("5 is the very best age to celebrate!")
}
  1. 运行您的代码。
  2. 验证输出窗格中是否显示了 Happy Birthday, Rover!,并且其下方是否依次显示了 You are already 5! 和 5 is the very best age to celebrate!
Happy Birthday, Rover!
You are already 5!
5 is the very best age to celebrate!

添加生日蛋糕

生日祝福语需要一个以生日为主题的图形,例如蛋糕图形。您可以通过另外添加几行输出语句(由字母、键盘符号和 println() 组成)在生日祝福语中添加蛋糕图形。

从上面的解决方案代码往下继续。

  1. 在代码中用于输出 Happy Birthday 和 You are already 5 的两个 println() 语句之间,添加下面几行输出语句,如下所示。这些语句的输出会生成一个蛋糕图形。最后一个 println() 语句的引号中间没有文本,这会输出一个空行。
    println("   ,,,,,   ")
    println("   |||||   ")
    println(" =========")
    println("@@@@@@@@@@@")
    println("{~@~@~@~@~}")
    println("@@@@@@@@@@@")
    println("")

为帮助他人理解您的代码,您可以在输出蛋糕图形的语句之前添加注释。如果您运行代码,输出看起来不会有任何不同,因为注释只是供您和开发者查看的信息,并非给系统的命令。代码内注释以 // 开头,后跟文本,如下所示。

// This is a comment line
// This is another comment
  1. 在输出蛋糕图形的语句之前添加注释:// Let's print a cake!。
  2. 在输出空行的语句之前添加注释:// This prints an empty line。

您的代码应该如以下代码所示。

fun main() {
    println("Happy Birthday, Rover!")

    // Let's print a cake!
    println("   ,,,,,   ")
    println("   |||||   ")
    println(" =========")
    println("@@@@@@@@@@@")
    println("{~@~@~@~@~}")
    println("@@@@@@@@@@@")

    // This prints an empty line.
    println("")

    println("You are already 5!")
    println("5 is the very best age to celebrate!")
}
  1. 运行您的代码,输出应如下所示。
Happy Birthday, Rover!
   ,,,,,
   |||||
 =========
@@@@@@@@@@@
{~@~@~@~@~}
@@@@@@@@@@@

You are already 5!
5 is the very best age to celebrate!

3. 创建和使用变量

在变量中存储 Rover 的年龄

  1. 在您截止到目前完成的代码中,请注意您是如何将同一个年龄数字重复两次的。

其实您可以不必重复此数字,而将其作为变量存储在一个位置,就像将数字放到一个框中并为其命名一样。然后,您就可以在需要该值时随时使用此变量名称。而且,如果年龄改变了,您只需更改程序中的一处即可。更改此变量后,系统会在使用该变量的各处输出正确的年龄值。

  1. 在您的程序中,添加以下代码作为 main() 函数的第一行代码,以创建一个名为 age、值为 5 的变量,如下所示。(必须将此行置于 println() 语句前。)
val age = 5

此行表示:

  • val 是 Kotlin 使用的一个特殊单词,称为关键字,用于表示紧随其后的是变量名称。
  • age 是变量的名称。
  • = 使 age(在其左边)的值等于其右边的值。在数学中,单个等号用于表示等号两边的值相等。与数学中不同,在 Kotlin 中,单个等号用于将等号右边的值赋予等号左边的指定变量。

开发者会这样说:此行声明了一个名为 age 的变量,其赋值为 5。

如需在输出语句中使用变量,您需要在变量前后使用一些符号来告诉系统紧随其后的内容不是文本而是变量。系统需要输出变量的值,而非输出文本。为此,您需要将变量放在大括号内并在前面加上美元符号,如下例所示。

${variable}
  1. 在您的代码中,将两条输出语句中的数字 5 替换为 age 变量,如下所示。
println("You are already ${age}!")
println("${age} is the very best age to celebrate!")
  1. 运行您的代码,两条祝福语应显示相同的年龄。
  2. 将变量的值更改为其他值。例如,您可以按天而非按年显示 Rover 的年龄。为此,请将年龄乘以 365,忽略闰年。您可以在创建变量之际进行此计算,如下所示。
val age = 5 * 365
  1. 再次运行您的代码,您会看到两条祝福语现在显示的年龄以天为单位。
Happy Birthday, Rover!
   ,,,,,
   |||||
 =========
@@@@@@@@@@@
{~@~@~@~@~}
@@@@@@@@@@@

You are already 1825!
1825 is the very best age to celebrate!
  1. [可选] 更改输出的祝福语的文本,使其更符合以天为单位的表述。例如,更改为如下所示的内容:
You are already 1825 days old!
1825 days old is the very best age to celebrate!

将文本放入变量中

您不仅可以将数字放入变量中,还可以将文本放入变量中。

  1. 在 age 变量下,添加名为 name 的变量用于表示过生日的人的名字,并将其值设置为 "Rover"。
val name = "Rover"
  1. 将生日祝福语中的人名 Rover 替换为该变量,如下所示。
println("Happy Birthday, ${name}!")

输出语句中可以包含多个变量。

  1. 使用 name 变量将 Rover 添加到包含年龄的祝福语中,如下所示。
println("You are already ${age} days old, ${name}!")

完成后的代码应如下所示。

fun main() {

    val age = 5 * 365
    val name = "Rover"

    println("Happy Birthday, ${name}!")

    // Let's print a cake!
    println("   ,,,,,   ")
    println("   |||||   ")
    println(" =========")
    println("@@@@@@@@@@@")
    println("{~@~@~@~@~}")
    println("@@@@@@@@@@@")

    // This prints an empty line.
    println("")

    println("You are already ${age} days old, ${name}!")
    println("${age} days old is the very best age to celebrate!")
}

祝贺您!现在,您可以创建包含文本和用符号创建的图形的祝福语,使用变量存储数字和文本,并使用变量输出文本。

4. 输出带边框的生日横幅

在此任务中,您将创建一条生日横幅,然后学习如何利用重复和重复使用代码的技巧来简化该代码,并了解这样做的好处何在。

创建简单的生日横幅

  1. 在 https://developer.android.com/training/kotlinplayground 中,将光标置于代码中的某个位置。
  2. 右键点击以打开菜单,然后选择 Select All。
  3. 按 Backspace 键或 Delete 键可删除所有代码。
  4. 将下面的代码复制并粘贴到编辑器中。
fun main() {
    println("=======================")
    println("Happy Birthday, Jhansi!")
    println("=======================")
}
  1. 运行您的程序,查看控制台中输出的横幅。
=======================
Happy Birthday, Jhansi!
=======================

创建用于输出边框的函数

您刚刚粘贴和运行的代码是一个名为 main() 的函数,其中包含三条输出语句。当您按 Run 按钮时,系统会执行该函数及其中的所有代码。

您的 Kotlin 程序必须始终具有一个 main() 函数。除此之外,您还可以创建和使用自己的函数。正如变量可以帮助您避免重复工作一样,函数也可以帮助您避免多次编写相同的代码。在您的代码中,横幅顶部和底部的输出语句完全相同。所以,让我们创建并使用一个函数来输出这些边框。

  1. 在编辑器中,在 main() 函数下方插入一个空行,这只是为了给您提供一些操作空间。系统会忽略空行,因此您可以根据组织代码的需要,在任意位置插入空行。
  2. 创建一个函数。以 fun 关键字开头,后跟名称 printBorder、一对圆括号 () 和一对大括号 {},如下所示。
fun printBorder() {}

关于函数命名的说明:

  • 请注意,函数 printBorder 的名称以小写的动词开头。函数名称几乎总是以小写的动词开头,并且名称应描述函数的功能。例如:print() 或此处的 printBorder()。
  • 另请注意,名称内的第二个单词以大写字母开头。这种样式称为“驼峰式大小写”,能够使名称更清晰易读。再多举两个名称的例子,譬如 drawReallyCoolFancyBorder 和 printBirthdayMessage。
  1. 用 printBorder 函数的右大括号 } 另起一行,并在两个大括号之间添加一个空行,让您有足够空间可以添加更多代码。让右大括号 } 独占一行,这样更容易看清函数结束之处。
  2. 在 main() 函数内,复制用于输出边框的输出语句,并将其粘贴到 printBorder() 函数的大括号之间。

完成后的 printBorder() 函数应如下所示。

fun printBorder() {
    println("=======================")
}

如需使用或调用一个函数,请使用函数名称加上圆括号。请注意,您一直就是这样使用 println() 的!因此,为了使用 printBorder 函数,请在代码中的任意所需位置调用 printBorder()。

  1. 在 main() 函数中,将使用 println() 输出边框线的代码行替换为对 printBorder() 函数的调用。完成后的代码应如下所示。
fun main() {
    printBorder()
    println("Happy Birthday, Jhansi!")
    printBorder()
}

fun printBorder() {
    println("=======================")
}
  1. 运行您的代码,确保所有代码都能像先前一样正常运行。

请注意,如果更改代码使其更易于使用或效果更好而又不会改变输出,那么这种更改称为重构。

重复边框图案

请看边框线,它其实是相同的符号不断重复。因此,您不是指示:

“输出这个由 23 个符号组成的字符串“,

而是这样指示:

”输出这 1 个符号 23 次“。

在代码中,您可以使用 repeat() 语句发出此指令。

  1. 在 printBorder() 函数中,使用 repeat() 语句输出 23 次等号。
  2. 不要使用 println(),而是使用 print(),以免在输出每个“=”之后另起一行。

代码如下。您现在有一条指令用于输出等号,如需重复执行该指令 23 次,需要使用 repeat() 语句。

fun printBorder() {
    repeat(23) {
        print("=")
    }
}
  • repeat() 语句以 repeat 开头,后跟 ()。此类语句称为“循环”,因为您将同一个代码重复或循环了多次。稍后您将学习创建循环的其他方法。
  • 圆括号 () 内是重复的次数,
  • 后跟大括号 {},
  • 大括号 {} 内是要重复的代码。
  1. 在 printBorder() 函数中 repeat() 语句的右大括号 } 之后(即用于输出边框线的语句结束之后),添加一个 println() 语句以输出换行符。

现在,您的代码应如下所示。

fun printBorder() {
    repeat(23) {
        print("=")
    }
    println()
}

main() 函数中的代码不变,您的整个程序应如下所示。

fun main() {
    printBorder()
    println("Happy Birthday, Jhansi!")
    printBorder()
}

fun printBorder() {
    repeat(23) {
        print("=")
    }
    println()
}
  1. 运行您的代码。输出应当与先前一样,但这次您只需指定“=”符号一次即可创建边框!
=======================
Happy Birthday, Jhansi!
=======================

使用参数更改边框

如果您想创建使用不同符号的边框(例如下面这些边框),该怎么办?

%%%%%%%%%%%%%%%%%%%%%%%

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

您可以为这些不同的符号各定义一个单独的函数。不过,有一种方法可以更高效地做到这一点。您可以重复使用已编写的函数并以更灵活的方式来使用,使其适用于多种不同符号。

函数的一个优点在于,您可以使用参数为其提供输入。在前面的 Codelab 中,当您开始了解 main() 时,曾接触过这方面的一些皮毛。在此步骤中,您将向 printBorder() 函数添加一个参数,使其可以输出您提供的任何边框图案。

  1. 在 main() 的第一行,为边框图案创建一个名为 border 的变量。此变量会让文本重复输出,生成边框。
val border = "%"
  1. 现在,将该 border 变量作为参数传递到对 printBorder() 函数的两个调用中。为此,您需要将 border 放到圆括号 () 内,正如您为 println() 提供要输出的文本时一样。

您的 main() 函数应如以下代码所示。

fun main() {
    val border = "%"
    printBorder(border)
    println("Happy Birthday, Jhansi!")
    printBorder(border)
}

printBorder() 函数会将此 border 的值作为输入,并算出如何输出完整边框。

  1. 运行您的代码。您的代码不会执行,相反,您会在代码旁边看到错误图标。dd0286b7414cea42.png
  2. 查看输出面板,那里也会显示错误消息。

与以前一样,消息会指出发生错误之处,并给出有关错误可能原因的提示。重要的内容如下:Too many arguments for public fun printBorder()。您调用了 printBorder() 函数并将边框作为输入传递。但是,printBorder() 函数定义目前不接受任何输入。

  1. 通过在 printBorder() 函数定义中添加代表边框的参数来修复此错误。如下所示,请看第一行代码。
fun printBorder(border: String) {
    repeat(23) {
        print("=")
    }
    println()
}
  • 请注意,该参数的名称为 border。
  • 名称后跟冒号 :
  • 以及 String 一词(说明这是什么种类或类型的参数)。

String 是由字符组成并用引号括起来的一段文本。您可以将其想象成就像珠子串成一串形成项链一样,字符排列起来构成单词和文本。将该参数指定为 String 有助于系统将您的参数强制设置为文本而非数字等其他类型。

  1. 运行您的代码。printBorder() 函数现在接受边框 String 作为输入。main() 中的代码使用 border 作为参数调用 printBorder(border)。您的代码应当正常运行而不会出现错误。
  2. 在控制台中查看您的程序的输出,是否仍显示与之前相同的边框?
=======================
Happy Birthday, Jhansi!
=======================

这不是预期行为!因为您是想以“%”符号绘制边框,而程序仍在使用“=”符号输出边框。在接下来的步骤中,您要调查发生这种情况的原因。

  1. 在编辑器中,注意灰色的感叹号。此图标表示警告。警告是指代码存在需要注意的问题,但这些问题不会阻止代码运行。7579663a694ef6bd.png
  2. 将鼠标悬停在感叹号上,系统即会显示一条消息,内容为:"Parameter 'border' is never used." 此警告解释了输出中存在的问题。您向函数传递了代表边框的新字符串,但没有将该字符串用于输出。
  3. 更改 printBorder() 函数以使用传入的 border 参数而非输出“=”。这样做的效果与 border 是函数内定义的变量完全相同。
fun printBorder(border: String) {
    repeat(23) {
        print(border)
    }
    println()
}
  1. 再次运行您的代码。输出应如下所示。
%%%%%%%%%%%%%%%%%%%%%%%
Happy Birthday, Jhansi!
%%%%%%%%%%%%%%%%%%%%%%%

太棒了,问题修复了!下面是完成后的代码。

fun main() {
    val border = "%"
    printBorder(border)
    println("Happy Birthday, Jhansi!")
    printBorder(border)
}

fun printBorder(border: String) {
    repeat(23) {
        print(border)
    }
    println()
}

无需添加太多代码,就大幅提高了使用 printBorder() 函数时的灵活性。现在,只要略微更改便可以输出由不同符号组成的边框。

  1. [可选] 如果只允许更改 main() 函数中的一行代码,如何才能输出如下所示的生日横幅?
***********************
Happy Birthday, Jhansi!
***********************
:::::::::::::::::::::::
Happy Birthday, Jhansi!
:::::::::::::::::::::::

修改函数以使用两个参数

如果您想使用由多个字符组成的其他图案,例如 "'-._,-'",该怎么办?您不能重复使用这一图案 23 次,否则就会太长。也许,您可以重复 4 次。通过在 printBorder() 的 repeat() 语句中更改重复次数可以做到这一点。不过,还有更好的办法!

您可以通过以下两方面定义一个更复杂精致的边框:

  • 需要重复的图案(您已完成了)
  • 您希望此图案重复的次数

您可以分别为图案和重复次数各创建一个变量,然后将两条信息都传递给 printBorder() 函数。

  1. 在 main() 中,将边框更改为 "'-._,-'" 图案。
val border = "`-._,-'"
  1. 运行代码,注意图案现在过长。
  2. 在 main() 的 border 定义下,为重复次数创建一个名为 timesToRepeat 的新变量。将其值设置为 4。
val timesToRepeat = 4
  1. 在 main() 中,调用 printBorder() 时,将重复次数添加为第二个参数。使用逗号分隔两个参数。
printBorder(border, timesToRepeat)

main() 函数现在应如下所示:

fun main() {
    val border = "`-._,-'"
    val timesToRepeat = 4
    printBorder(border, timesToRepeat)
    println("Happy Birthday, Jhansi!")
    printBorder(border, timesToRepeat)
}

与之前一样,此代码会显示错误,因为调用 printBorder() 的参数比 printBorder() 定义中的参数多。

  1. 修复 printBorder(),使其同时也接受重复次数作为输入。在参数后添加逗号,后跟另一个参数:timesToRepeat: Int. 函数定义的第一行现在如下所示。
fun printBorder(border: String, timesToRepeat: Int) {

请注意:

  • 逗号用于分隔两个参数。
  • timesToRepeat 是参数的名称,
  • 后跟冒号 :
  • 以及类型 Int. timesToRepeat 是一个数字,因此其类型为 Int(integer 的缩写,表示整数)而非 String。
  1. 在 printBorder() 内,更改 repeat 以使用 timesToRepeat 参数(而非数字 23)。您的 printBorder() 代码应如下所示。
fun printBorder(border: String, timesToRepeat: Int) {
    repeat(timesToRepeat) {
        print(border)
    }
    println()
}
  1. 运行您的代码。其输出如下所示。
`-._,-'`-._,-'`-._,-'`-._,-'
Happy Birthday, Jhansi!
`-._,-'`-._,-'`-._,-'`-._,-'
  1. 为了使此输出更完美,在 Happy Birthday 生日祝福语的开头插入两个空格。此时,输出应如下所示。
`-._,-'`-._,-'`-._,-'`-._,-'
  Happy Birthday, Jhansi!
`-._,-'`-._,-'`-._,-'`-._,-'

下面是横幅的最终代码:

fun main() {
    val border = "`-._,-'"
    val timesToRepeat = 4
    printBorder(border, timesToRepeat)
    println("  Happy Birthday, Jhansi!")
    printBorder(border, timesToRepeat)
}

fun printBorder(border: String, timesToRepeat: Int) {
    repeat(timesToRepeat) {
        print(border)
    }
    println()
}

祝贺您!学完函数、参数、变量和重复循环,您就已掌握了几乎所有程序中都会用到的基本构建基块。

请休息一下后执行下面的下一个任务,届时您将创建更多函数和循环,只需编写几行代码即可构建一个插有正确数量的蜡烛的巨大蛋糕。

5. 创建插有蜡烛的多层蛋糕

在此任务中,您将升级生日蛋糕代码,使其始终具有正确的尺寸,并根据年龄插上正确数量的蜡烛。

  • 您总共要创建 3 个函数,用于绘制插有蜡烛的多层蛋糕。
  • 您将在 repeat() 内使用另一个 repeat(),创建一个“嵌套循环”。
  • 构建此代码的方法可用于构建任何程序,先构建框架,然后添加细节。这称为“自上而下开发”。
  • 我们对此练习的说明并不详尽,如果遇到困难,您可以参考完成后的代码。

下面是您要“烤”的蛋糕的图形:

 ,,,,,,,,,,,,,,,,,,,,,,,,
 ||||||||||||||||||||||||
==========================
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@

以下是相关说明。

创建 main() 函数

  1. 在编辑器中,将您的代码重置为 Hello, world! 程序。
  2. 您可以移除 main() 的参数,因为您不会再使用此参数。
  3. 在 main() 中,创建变量 age 并将其设置为 24。
  4. 在 main() 中,创建第二个变量 layers 并将其设置为 5。
  5. 在 main() 中,调用函数 printCakeCandles() 并传入 age。这会留下错误,因为您尚未创建该函数。
  6. 同样,调用函数 printCakeTop(),也传入 age。
  7. 最后,调用函数 printCakeBottom(),并同时传入 age 和 layers 的层数。
  8. 为了消除错误,请在每行开头添加 // 注释掉三个函数调用,如下所示。通过此方法,您就能在编写代码时不触发错误。
  9. 运行程序,应该不会出现错误,但也不会执行任何操作。

您的 main() 函数应如以下代码所示。

fun main() {
    val age = 24
    val layers = 5
    // printCakeCandles(age)
    // printCakeTop(age)
    // printCakeBottom(age, layers)
}

创建 printCakeTop()

用于输出蛋糕顶部的 printCakeTop() 函数是一行等号,与您先前在此 Codelab 中创建的 printBorder() 函数几乎一样。

==========================
  1. 在 main() 函数下添加一个空行,然后创建函数 printCakeTop(),该函数接受一个类型为 Int 的参数 age。
  2. 在函数内,使用 repeat() 语句输出一个等号 age+2 次。多出的两个等号使蜡烛不会落到蛋糕两侧的范围之外。
  3. 最后,在完成 repeat() 后输出一个空行。
  4. 在 main() 中,从 printCakeTop() 的代码行开头移除两个 // 符号,因为函数现在已经存在。
printCakeTop(age)

以下是完成后的函数。

fun printCakeTop(age: Int) {
    repeat(age + 2) {
        print("=")
    }
    println()
}
  1. 运行您的代码,看看蛋糕顶部的输出效果。

创建 printCakeCandles()

每根蜡烛都由两个符号组成:一个逗号 (,) 代表火焰,一根竖线 (|) 代表烛身。

,,,,,,,,,,,,,,,,,,,,,,,,

||||||||||||||||||||||||

为了用一个函数做到这一点,需要两个 repeat() 语句:一个针对火焰,另一个针对烛身。

  1. 在 main() 函数和 printCakeTop() 函数下,创建一个新函数 printCakeCandles(),该函数接受一个类型为 Int 的参数 age。
  2. 在函数内,使用 repeat() 语句输出一个逗号 , 代表火焰。
  3. 重复此输出 age 次。
  4. 最后,输出一个空行。
  5. 添加输出语句,以输出一个空格来插入蜡烛。
  6. 在下方,重复上述步骤创建第二个 repeat() 语句,以竖线 | 输出烛身。
  7. 最后,使用 println() 输出一个新行。
  8. 在 main() 中,从 printCakeCandles() 的代码行开头移除两个 // 符号。
printCakeCandles(age)
  1. 运行您的代码,看看蛋糕顶部加上蜡烛的输出效果

解决方案:

fun printCakeCandles(age: Int) {
    print(" ")
    repeat(age) {
        print(",")
    }
    println() // Print an empty line

    print(" ") // Print the inset of the candles on the cake
    repeat(age) {
        print("|")
    }
    println()
}

创建 printCakeBottom()

在此函数中,您要绘制宽度为 age + 2 的蛋糕底部,绘制的高度为指定层数。

@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
  • 也就是说,您的函数需要两个参数:一个表示宽度 (age),另一个表示高度 (layers)。
  • 为了输出蛋糕底部,首先要重复 @ 符号 age + 2 次以输出一层。然后,重复输出一层 layers 次。

绘制 @ 符号 age+2 次以创建一层蛋糕底部

  1. 在现有函数下方,创建具有两个参数 age 和 layers 的函数 printCakeBottom(),这两个参数的类型均为 Int。
  2. 在该函数内,使用 repeat() 语句输出一层 @ 符号 @(age + 2 次)。最后,输出一个空行,如下所示。
fun printCakeBottom(age: Int, layers: Int) {
    repeat(age + 2) {
        print("@")
    }
    println()
}
  1. 在 main() 中,从 printCakeBottom(age, layers) 的代码行开头移除两个 // 符号。
  2. 运行您的代码,验证其能否输出一行蛋糕底部。
 ,,,,,,,,,,,,,,,,,,,,,,,,
 ||||||||||||||||||||||||
==========================
@@@@@@@@@@@@@@@@@@@@@@@@@@

嵌套 repeat() 语句

如需输出多层相同的蛋糕底部,您可以指示:

对于第 1 层,将符号重复 12 次:@@@@@@@@@@@@

对于第 2 层,将符号重复 12 次:@@@@@@@@@@@@

对于第 3 层,将符号重复 12 次:@@@@@@@@@@@@

或者,您可以发出如下更简洁的指示:

重复三层:

将符号重复 12 次。

@@@@@@@@@@@@

@@@@@@@@@@@@

@@@@@@@@@@@@

现在,您可以使用 repeat() 语句让代码更简洁。您可以将一个 repeat() 语句放到另一个 repeat() 语句内。这样一来,就可以在 repeat() 语句内创建 repeat() 语句,用于将符号输出特定次数和特定层数。

使用嵌套的 repeat() 输出蛋糕层

  1. 围绕函数内的所有代码添加第二个 repeat() 语句。重复此循环 layers 次。
  2. 在 main() 中,仅从 printCakeBottom() 的代码行中移除两个 //。
printCakeBottom(age, layers)
  1. 运行您的代码,看看整个蛋糕的输出效果。

printCakeBottom() 的解决方案。

fun printCakeBottom(age: Int, layers: Int) {
    repeat(layers) {
        repeat(age + 2) {
            print("@")
        }
        println()
    }
}

祝贺您!您已完成了一个相当复杂的程序,其中包含多个函数和一个嵌套的 repeat 语句。您的蛋糕始终都会插有正确数量的蜡烛!

程序的最终输出应为:

 ,,,,,,,,,,,,,,,,,,,,,,,,
 ||||||||||||||||||||||||
==========================
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@
@@@@@@@@@@@@@@@@@@@@@@@@@@

6. 解决方案代码

fun main() {
    val age = 24
    val layers = 5
    printCakeCandles(age)
    printCakeTop(age)
    printCakeBottom(age, layers)
}

fun printCakeCandles(age: Int) {
    print (" ")
    repeat(age) {
          print(",")
    }
    println() // Print an empty line

    print(" ") // Print the inset of the candles on the cake
    repeat(age) {
        print("|")
    }
    println()
}

fun printCakeTop(age: Int) {
    repeat(age + 2) {
        print("=")
    }
    println()
}

fun printCakeBottom(age: Int, layers: Int) {
    repeat(layers) {
        repeat(age + 2) {
            print("@")
        }
        println()
    }
}

7. 问题排查

如果基于浏览器的 Kotlin 编程工具不执行您的代码或显示与代码无关的意外错误,您可以尝试以下办法:

  • 使用 Shift+Reload 重新加载页面。
  • 稍等片刻,然后重试。

8. 总结

  • 使用 ${} 将输出语句的文本中的变量和计算括起来。例如:${age},其中的 age 就是变量。
  • 使用 val 关键字和名称创建变量。此值设定后即无法更改。使用等号为变量赋值。值的示例包括文本和数字。
  • String 是用引号括起来的文本,例如 "Hello"。
  • Int 是正整数或负整数,例如 0、23 或 -1024。
  • 您可以将一个或多个参数传入函数中供函数使用,例如:fun printCakeBottom(age:Int, layers:Int) {}
  • 使用 repeat() {} 语句重复一组指令若干次。例如,repeat (23) { print("%") } 或 repeat (layers) { print("@@@@@@@@@@") }
  • 循环是用于多次重复某指令的一个指令。repeat() 语句就是循环的一个示例。
  • 您可以嵌套循环,即,将循环放到循环内。例如,您可以在 repeat() 语句内创建一个 repeat() 语句,用于将符号输出若干次和若干行,就像您对蛋糕层所做的那样。

有关函数参数用法的摘要:如需使用包含参数的函数,您需要执行以下三项操作:

  • 将参数和类型添加到函数定义中:printBorder(border: String)
  • 在函数内使用参数:println(border)
  • 在调用函数时提供参数:printBorder(border)

9. 了解更多内容

以下是您在此 Codelab 中所学的 Kotlin 概念的官方文档。