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

## 比较运算符

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 比较运算符.

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

``````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.

### 布尔运营商

``````val doesOneEqualTwo = (1 == 2)
``````

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

``````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 `真的`.

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 `>=`.

### 布尔逻辑 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 `错误的`.

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 `真的`.

``````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
``````

``````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`.

## 如果表达式

``````如果 (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!

### 别的表达式

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.

``````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.

### 别的 - 如果表达式

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.

### 封装变量

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

``````var hoursWorked = 45

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

println(price)
``````

``````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`.

## 循环

### 徘徊

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`.

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.

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.

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.

© 2021 Razeware LLC