首页 安卓& Kotlin Books Kotlin学徒

4
基本控制流量 由伊琳娜加拉塔撰写

在编写计算机程序时,您需要能够告诉计算机在不同方案中做什么。例如,如果用户删除减法按钮,则在用户删除添加按钮和另一件事,则需要执行一件事。

在计算机编程术语中,这个概念被称为 控制流。它是如此命名,因为程序的流量由各种方法控制。在本章中,您将学习如何通过使用语法来控制程序中的编程中的决策和重复任务。你也会学到 布尔斯,它表示真假值,以及如何使用这些来比较数据。

在Intellij开辟一个项目,沿着!

比较运算符

You’ve seen a few types now, such as Int, Double and String. Here you’ll learn about another type, one that will let you compare values through the 比较运算符.

执行比较时,例如寻找两个数字的比较大,答案要么 真的 或者 错误的. Kotlin has a data type just for this! It’s called a Boolean, after a rather clever man named George Boole who invented an entire field of mathematics around the concept of true and false.

这就是您在Kotlin中使用布尔的方式:

val yes: Boolean = true
val no: Boolean = false

并且由于Kotlin的类型推断,您可以留下型注释:

val yes = true
val no = false

A Boolean can only be either true or false, denoted by the keywords 真的 and 错误的. In the code above, you use the keywords to set the state of each constant.

布尔运营商

布尔斯通常用于比较值。例如,您可能有两个值,并且您想知道它们是否相等:它们是(true)或它们不是(false)。

在Kotlin,你用它使用这件事 平等运营商, which is denoted by ==. Try it out:

val doesOneEqualTwo = (1 == 2)

Kotlin infers that 做esOneEqualTwo is a Boolean. Clearly, 1 does not equal 2, and therefore 做esOneEqualTwo will be 错误的.

同样,您可以找到两个值是否有两个值 不是 equal using the != operator:

val doesOneNotEqualTwo = (1 != 2)

This time, the comparison is true because 1 does not equal 2, so 做esOneNotEqualTwo will be 真的.

The prefix ! operator, also called the 不是运营商,切换为false和false。另一种写上述方法是:

val alsoTrue = !(1 == 2)

Because 1 does not equal 2, (1 == 2) is 错误的, and then ! flips it to 真的.

Two more operators let you determine if a value is greater than (>) or less than (<) another value. You’ll likely know these from mathematics:

val isOneGreaterThanTwo = (1 > 2)
val isOneLessThanTwo = (1 < 2)

And it’s not rocket science to work out that isOneGreaterThanTwo will equal 错误的 and isOneLessThanTwo will equal 真的.

还有一个运算符,可让您测试值是否小于 或者 equal to another value: <=. It’s a combination of < and ==, and will therefore return 真的 如果 the first value is either less than the second value or equal to it.

Similarly, there’s an operator that lets you test if a value is greater than or equal to another — you may have guessed that it’s >=.

布尔逻辑

上面的每个例子只测试一个条件。当George Boole发明了Boolean时,他比这些谦卑的开端更多地计划。他发明了布尔逻辑,它允许您组合多个条件来形成结果。

使用条件的一种方法是使用 . When you AND together two Booleans, the result is another Boolean. If both input Booleans are 真的, then the result is 真的. Otherwise, the result is 错误的.

In Kotlin, the operator for Boolean AND is &&, used like so:

val and = true && true

In this case, and will be 真的. If either of the values on the right was 错误的, then and would be 错误的.

通过使用的另一种组合条件的方法 或者 . When you OR together two Booleans, the result is 真的 如果 任何一个 of the input Booleans is 真的. Only if 两个都 input Booleans are 错误的 will the result be 错误的.

In Kotlin, the operator for Boolean OR is ||, used like so:

val or = true || false

In this case, 或者 will be 真的. If both values on the right were 错误的, then 或者 would be 错误的. If both were 真的, then 或者 would still be 真的.

在Kotlin中,布尔逻辑通常适用于多个条件。也许你想确定两个条件是否为真;在这种情况下,您可以使用和。如果您只关心两个条件中的一个是否真实,那么您将使用或使用。

例如,考虑以下代码:

val andTrue = 1 < 2 && 4 > 3
val andFalse = 1 < 2 && 3 > 4

val orTrue = 1 < 2 || 3 > 4
val orFalse = 1 == 2 || 3 == 4

这些测试中的每一个都在两个单独的条件下,将它们与或或或或或。

也可以使用布尔逻辑来组合两个以上的比较。例如,您可以形成一个复杂的比较,如下所示:

val andOr = (1 < 2 && 3 > 4) || 1 < 4

括号歧义表达式。第一个Kotlin评估括号内的子表达式,然后遵循以下步骤评估完整表达式:

1. (1 < 2 && 3 > 4) || 1 < 4
2. (true && false) || true
3. false || true
4. true

字符串平等

有时您想要确定两个字符串是否相等。例如,在照片中命名动物的儿童游戏需要确定玩家是否正确回答。

In Kotlin, you can compare strings using the standard equality operator, ==, in exactly the same way as you compare numbers. For example:

val guess = "做g"
val dogEqualsCat = guess == "cat"

Here, 做gEqualsCat is a Boolean that in this case equals 错误的, because "做g" does not equal "cat". Simple!

就像数字一样,您可以不仅可以相等地比较,而且还可以确定一个值是否大于或更低的另一个值。例如:

val order = "cat" < "做g"

This syntax checks if one string comes before another alphabetically. In this case, 或者der equals 真的 because "cat" comes before "做g".

迷你练习

  1. Create a constant called myAge and set it to your age. Then, create a constant named isTeenager that uses Boolean logic to determine if the age denotes someone in the age range of 13 to 19.
  2. Create another constant named theirAge and set it to the age 30. Then, create a constant named 两个都Teenagers that uses Boolean logic to determine if both you and them are teenagers.
  3. Create a constant named reader and set it to your name as a string. Create a constant named author and set it to the name Richard Lucas. Create a constant named authorIsReader that uses string equality to determine if reader and author are equal.
  4. Create a constant named readerBeforeAuthor which uses string comparison to determine if reader comes before author.

如果表达式

控制程序流程的第一种和最常用方式是通过使用 如果 expression,这允许该计划仅做某事 如果 某种情况是真的。例如,尝试键入并运行以下操作:

如果 (2 > 1) {
  println("Yes, 2 is greater than 1.")
}

This is a simple 如果 expression. If the condition is true, then the expression will execute the code between the braces. If the condition is false, then the expression won’t execute the code between the braces. It’s as simple as that!

期限 如果 expression 这里使用而不是 如果 statement, since, unlike many other programming languages, a value is returned from the 如果 expression. The value returned is the value of the last expression in the 如果 block.

您不需要使用返回的值或将其分配给变量。您将在返回以下值时显示更多。

别的表达式

You can extend an 如果 表达 to provide code to run in case the condition turns out to be false. This is known as the else子句。这是一个例子:

val animal = "Fox"

if (animal == "Cat" || animal == "Dog") {
  println("Animal is a house pet.")
} else {
  println("Animal is not a house pet.")
}

Here, if animal equals either "Cat" 或者 "Dog", then the expression will run the first block of code. If animal does not equal either "Cat" 或者 "Dog", then the expression will run the block inside the else part of the 如果 expression, printing the following to the console:

Animal is not a house pet.

You can also use an 如果-else 表达 on one line. Let’s take a look at how this can make your code more concise and readable.

如果您想确定两个变量的最小和最大值,请您 可以 use 如果 expressions like so:

val a = 5
val b = 10

val min: Int
if (a < b) {
  min = a
} else {
  min = b
}

val max: Int
if (a > b) {
  max = a
} else {
  max = b
}

By now you know how this works, but it’s a lot of code. Let’s take a look at how we can improve this using the fact that the 如果-else 表达 returns a value.

只需卸下括号并将其全部放在一行上,如下所示:

val a = 5
val b = 10

val min = if (a < b) a else b
val max = if (a > b) a else b

In the first example, the condition is a < b. If this is true, the result assigned back to min will be the value of a; if it’s false, the result will be the value of b. So min is set to 5. In the second example, max is assigned the value of b, which is 10.

我相信你会同意这更简单!这是一个例子 惯用 代码,这意味着您正在以特定编程语言的预期方式编写代码。您希望在他们使代码更清晰的情况下使用成语,因为它不仅使得代码更好,而且它允许其他开发人员熟悉语言以快速理解您的代码。

笔记: Because finding the greater or smaller of two numbers is such a common operation, the Kotlin standard library provides two functions for this purpose: max() and min(). If you were paying attention earlier in the book, then you’ll recall you’ve already seen these.

别的 - 如果表达式

But you can go even further than that with 如果 expressions. Sometimes you want to check one condition, then another. This is where else-if comes into play, nesting another 如果 clause in the else clause of a previous 如果 clause.

You can use else-if like so:

val hourOfDay = 12

val timeOfDay = if (hourOfDay < 6) {
  "Early morning"
} else if (hourOfDay < 12) {
  "Morning"
} else if (hourOfDay < 17) {
  "Afternoon"
} else if (hourOfDay < 20) {
  "Evening"
} else if (hourOfDay < 24) {
  "Late evening"
} else {
  "INVALID HOUR!"
}
println(timeOfDay)

These nested 如果 clauses test multiple conditions one by one until a true condition is found. Only the code associated with that first true condition is executed, regardless of whether subsequent else-if conditions are true. In other words, the order of your conditions matters!

You can add an else clause at the end to handle the case where none of the conditions are true. This else clause is optional if you don’t need it; in this example you need it, to ensure that timeOfDay has a valid value by the time you print it out.

In this example, the 如果 表达 takes a number representing an hour of the day and converts it to a string representing the part of the day to which the hour belongs. Working with a 24-hour clock, the conditions are checked in order, one at a time:

  • 第一个检查是看一小时的时间小于6.如果是的话,这意味着这是清晨。
  • If the hour is not less than 6, the expression continues to the first else-if, where it checks the hour to see if it’s less than 12.
  • 然后,随着条件证明假的,表达式检查小时,看看它是否小于17,那么小于20,那么小于24。
  • 最后,如果小时超出范围,则表达式返回值无效。

In the code above, the hourOfDay constant is 12. Therefore, the code will print the following:

Afternoon

Notice that even though both the hourOfDay < 20 and hourOfDay < 24 conditions are also true, the expression only executes and returns the first block whose condition is true; in this case, the block with the hourOfDay < 17 condition.

短路

An important fact about 如果 expressions and the Boolean operators is what happens when there are multiple Boolean conditions separated by ANDs (&&) or ORs (||).

考虑以下代码:

如果 (1 > 2 && name == "Matt Galloway") {
  // ...
}

The first condition of the 如果 expression, 1 > 2 is 错误的. Therefore the whole expression cannot ever be 真的. So Kotlin will not even bother to check the second part of the expression, namely the check of name.

同样,请考虑以下代码:

如果 (1 < 2 || name == "Matt Galloway") {
  // ...
}

Since 1 < 2 is 真的, the whole expression must be 真的 as well. Therefore once again, the check of name is not executed. This will come in handy later on when you start dealing with more complex data types.

封装变量

如果 表达式介绍一个新概念, 范围,这是一种通过使用括号封装变量的方法。

想象一下,您想计算为客户收费的费用。这是你所做的交易:

您每小时赚25美元,每小时40小时,此后每小时50美元。

使用Kotlin,您可以以这种方式计算您的费用:

var hoursWorked = 45

var price = 0
if (hoursWorked > 40) {
  val hoursOver40 = hoursWorked - 40
  price += hoursOver40 * 50
  hoursWorked -= hoursOver40
}
price += hoursWorked * 25

println(price)

此代码需要数小时数,如果是超过40则需要检查。如果是,则代码计算超过40的小时数并将其乘以50美元,然后将结果添加到价格上。然后代码从工作时间中减去40多小时的小时。它乘以25美元的剩余时间,并增加了总价格。

在上面的示例中,结果如下:

1250

The interesting thing here is the code inside the 如果 expression. There is a declaration of a new constant, hoursOver40, to store the number of hours over 40. Clearly, you can use it inside the 如果 statement.

但是,如果您在上面的代码结束时尝试使用它会发生什么?

println(price)
println(hoursOver40)

这将导致以下错误:

Unresolved reference: 'hoursOver40'

This error informs you that you’re only allowed to use the hoursOver40 constant within the scope in which it was created.

In this case, the 如果 表达 introduced a new scope, so when that scope is finished, you can no longer use the constant.

However, each scope can use variables and constants from its parent scope. In the example above, the scope inside of the 如果 表达 uses the price and hoursWorked variables, which you created in the parent scope.

迷你练习

  1. Create a constant named myAge and initialize it with your age. Write an 如果 表达 to print out Teenager 如果 your age is between 13 and 19, and Not a teenager 如果 your age is not between 13 and 19.
  2. Create a constant called answer and use a single line 如果-else 表达 to set it equal to the result you print out for the same cases in the above exercise. Then print out answer.

循环

循环 are Kotlin’s way of executing code multiple times. In this section, you’ll learn about one type of loop: the while loop.

如果您知道另一种编程语言,您将找到概念,也许甚至可以熟悉语法。

徘徊

A 循环时 repeats a block of code while a condition is true. You create a while loop this way:

while (/* CONDITION */) {
  /* LOOP CODE */
}

The loop checks the condition for every iteration. If the condition is 真的, then the loop executes and moves on to another iteration.

If the condition is 错误的, then the loop stops. Just like 如果 expressions, while loops introduce a scope.

The simplest while loop takes this form:

while (true) {
}

This is a while loop that never ends because the condition is always 真的. Of course, you would never write such a while loop, because your program would spin forever! This situation is known as an 无限循环虽然可能不会导致您的程序崩溃,但它很可能会导致计算机冻结。

Here’s a more useful example of a while loop:

var sum = 1

while (sum < 1000) {
  sum = sum + (sum + 1)
}

This code calculates a mathematical sequence, up to the point where the value is greater than 1000.

循环执行如下:

  • 在迭代1之前: sum = 1,循环条件= true
  • 迭代1: sum = 3,循环条件= true
  • 迭代2: sum = 7,循环条件= true
  • 迭代3: sum = 15,循环条件= true
  • 迭代4: sum = 31,循环条件= true
  • 迭代5后: sum = 63,循环条件= true
  • 迭代6: sum = 127,循环条件= true
  • 迭代7: sum = 255,循环条件= true
  • 迭代8: sum = 511,循环条件= true
  • 迭代9: sum = 1023,循环条件= false

After the ninth iteration, the sum variable is 1023, and therefore the loop condition of sum < 1000 becomes false. At this point, the loop stops.

重复循环

A variant of the while loop is called the 做循环. It differs from the while loop in that the condition is evaluated 在最后 循环而不是开始。

You construct a 做-while loop like this:

做 {
  /* LOOP CODE */
} while (/* CONDITION */)

Here’s the example from the last section, but using a repeat-while loop:

sum = 1

do {
  sum = sum + (sum + 1)
} while (sum < 1000)

In this example, the outcome is the same as before. However, that isn’t always the case; you might get a different result with a different condition. Consider the following while loop:

sum = 1

while (sum < 1) {
  sum = sum + (sum + 1)
}

Consider the corresponding 做-while loop, which uses the same condition:

sum = 1

do {
  sum = sum + (sum + 1)
} while (sum < 1)

In the case of the regular while loop, the condition sum < 1 is 错误的 right from the start. That means the body of the loop won’t be reached because the condition is checked at the beginning! The value of sum will equal 1 because the loop won’t execute any iterations.

In the case of the 做-while loop, sum will equal 3 because the loop executes once and then the condition is checked for the first time.

脱离循环

Sometimes you want to break out of a loop early. You can do this using the break statement, which immediately stops the execution of the loop and continues on to the code after the loop.

例如,考虑以下代码:

sum = 1

while (true) {
  sum = sum + (sum + 1)
  if (sum >= 1000) {
    break
  }
}

Here, the loop condition is 真的, so the loop would normally iterate forever. However, the break means the while loop will exit once the sum is greater than or equal to 1000.

你已经看到了如何以不同的方式编写相同的循环,展示在计算机编程中,通常有很多方法可以实现相同的结果。

您应该选择最容易读取的方法,以最佳方式读取和传达您的意图。这是一种方法,您将在足够的时间和练习中内化。

迷你练习

  1. Create a variable named counter and set it equal to 0. Create a while loop with the condition counter < 10 which prints out counter is X (where X is replaced with counter value) and then increments counter by 1.

  2. Create a variable named counter and set it equal to 0. Create another variable named roll and set it equal to 0. Create a 做-while loop.

Inside the loop, set roll equal to Random().nextInt(6) which means to pick a random number between 0 and 5. Then increment counter by 1.

笔记: Add the line import java.util.* to the top of your Kotlin file to be able to use Random.

Finally, print After X rolls, roll is Y where X is the value of counter and Y is the value of roll. Set the loop condition such that the loop finishes when the first 0 is rolled.

开奖结果3d

是时候测试了你的知识!如果您需要任何帮助,请在本章中查看材料中的解决方案。

  1. 以下代码有什么问题?
val firstName = "Joe"

if (firstName == "Howard") {
  val lastName = "Lucas"
} else if (firstName == "Ray") {
  val lastName = "Wenderlich"
}

val fullName = firstName + " " + lastName
  1. In each of the following statements, what is the value of the Boolean answer constant?
val answer1 = true && true
val answer2 = false || false
val answer3 = (true && 1 != 2) || (4 > 3 && 100 < 1)
val answer4 = ((10 / 2) > 3) && ((10 % 2) == 0)
  1. 假设棋盘上的正方形被留下向右,顶部到底部,0个是左上方的正方形,63是右下方。排在最低到底部的行,0到7.列被左右编号,0到7.给定棋盘上的当前位置,表示为行和列号,计算棋盘上的下一个位置,再次表示为一个行和列号。排序由0到63的编号确定.63之后的位置再次为0。

  2. 给定系数a,b和c,用这些系数计算对二次方程的解决方案。考虑到不同数量的解决方案(0,1或2)。如果您需要数学进修,那么这款关于二次方程的Wikipedia文章将有助于: //en.wikipedia.org/wiki/Quadratic_formula.

笔记: Add import kotlin.math.sqrt to the top of your file to access the sqrt operation.

  1. Given a month (represented with a string in all lowercase) and the current year (represented with an Int), calculate the number of days in the month. Remember that because of leap years, “february” has 29 days when the year is a multiple of 4 but not a multiple of 100. February also has 29 days when the year is a multiple of 400.

  2. Given a number as a Double value, determine if this number is a power of 2.

暗示: You can use log2(number) to find the base 2 logarithm of number. log2(number) will return a whole number if number is a power of two. Add import kotlin.math.log2 to the top of your file to use log2.

您还可以使用循环和没有对数来解决问题。

  1. 打印前10个动力的表2。

  2. 给定n个数字,计算第n个斐波纳契数。 (调用Fibonacci是1,1,2,3,5,8,13,...以1和1开头,将这些值加在一起以获取下一个值。下一个值是前两个的总和。所以下一个值在这种情况下,8 + 13 = 21.)

  3. 给定N个数字,计算n的阶乘。 (例:4因子等于1 * 2 * 3 * 4.)

  4. 给定2和12之间的数字,计算使用两个六面骰子滚动此数量的几率。通过彻底地循环所有组合来计算它,并计算给您该价值的结果的分数。不要使用公式。

关键点

  • You use the Boolean data type Boolean to represent true and false.
  • 比较运算符,所有这些都返回布尔,是:
Equal: `==`
Not equal: `!=`
Less than: `<`
Greater than: `>`
Less than or equal: `<=`
Greater than or equal: `>=`
  • You can use Boolean logic with && and || to combine comparison conditions.
  • You use 如果 expressions to make simple decisions based on a condition, and return a value.
  • You use else and else-if within an 如果 表达 to extend the decision-making beyond a single condition.
  • You can use a single line 如果-else 表达 to make your code more clear and concise.
  • 短路确保仅评估布尔表达的最小所需部分。
  • 变量和常量属于某个范围,超出您无法使用它们的范围。范围继承父母的可见变量和常量。
  • while 循环允许您多次执行某项任务,直到满足条件。
  • The break 陈述 lets you break out of a loop.

然后去哪儿?

Apps very rarely run all the way through the same way every time; depending on what data comes in from the internet or from user input, your code will need to make decisions on which path to take. With 如果 and else, you can have your code make decisions on what to do based on some condition.

In the next chapter, you’ll see how to use more advanced control flow statements. This will involve more loops like the while loop you saw in this chapter, and a new construct called the when expression.

有一个技术问题?想报告一个错误吗? 您可以向官方书籍论坛中的书籍作者提出问题和报告错误 这里.

有反馈分享在线阅读体验吗? 如果您有关于UI,UX,突出显示或我们在线阅读器的其他功能的反馈,您可以将其发送到设计团队,其中表格如下所示:

© 2021 Razeware LLC