# 3 基本控制流量 由MATT Galloway撰写

## 比较运算符

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

``````let yes: Bool = true
let no: Bool = false
``````

``````let yes = true
let 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.

### 布尔运营商

``````let doesOneEqualTwo = (1 == 2)
``````

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

``````let 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 not-operator, toggles true to false and false to true. Another way to write the above is:

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

``````let isOneGreaterThanTwo = (1 > 2)
let 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 Swift, the operator for Boolean AND is `&&`, used like so:

``````let and = true && true
``````

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

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

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

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

``````let andTrue = 1 < 2 && 4 > 3
let andFalse = 1 < 2 && 3 > 4

let orTrue = 1 < 2 || 3 > 4
let orFalse = 1 == 2 || 3 == 4
``````

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

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

### 字符串平等

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

``````let guess = "做 g"
let dogEqualsCat = guess == "cat"
``````

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

``````let order = "cat" < "做 g"
``````

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

### 切换BOOL.

A `Bool` often represents the state of something being “on” or “off”. In those cases, it’s common for the state to be toggled between states. For example, you could use a `Bool` to represent the state of a light switch in your application and toggle between the states “on” and “off”.

For these situations, there is a handy way to flip a `Bool` from `真的` to `错误的` and back again. Like so:

``````var switchState = true
switchState.toggle() // switchState = false
switchState.toggle() // switchState = true
``````

Here, the variable called `switchState` starts as `真的`. Then, after one `toggle`, it becomes `错误的`. After another `toggle` it’s set to `真的` again.

### 迷你练习

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 my age, which is 30. Then, create a constant named `两个都Teenagers` that uses Boolean logic to determine if both you and I 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 my name, Matt Galloway. 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`.

## IF语句

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

This is a simple `如果` statement. If the condition is true, then the statement will execute the code between the braces. If the condition is false, then the statement 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子句。这是一个例子：

``````let animal = "Fox"

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

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

`Animal is not a house pet.`

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

``````let hourOfDay = 12
var timeOfDay = ""

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

These nested `如果` statements 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 statements are checked in order, one at a time:

• 第一个检查是看一小时的时间小于6.如果是的话，这意味着这是清晨。
• If the hour is not less than 6, the statement 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 statement only executes the first block whose condition is true; in this case, the block with the `hourOfDay < 17` condition.

### 短路

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

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

The first condition of the `如果` statement, `1 > 2` is `错误的`. Therefore the whole expression cannot ever be `真的`.

So Swift will not even bother to check the second part of the expression, namely the check of `name`. Similarly, consider the following code:

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

Since `1 < 2` is `真的`, the whole expression must be `真的` no matter what the value of `name` is. 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 {
let hoursOver40 = hoursWorked - 40
price += hoursOver40 * 50
hoursWorked -= hoursOver40
}
price += hoursWorked * 25

print(price)
``````

`1250`

The interesting thing here is the code inside the `如果` statement. 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. But what happens if you try to use it at the end of the above code?

``````...

print(price)
print(hoursOver40)
``````

`Use of unresolved identifier '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.

### 三元条件运营商

If you wanted to determine the minimum and maximum of two variables, you could use `如果` statements, like so:

``````let a = 5
let b = 10

let min: Int
if a < b {
min = a
} else {
min = b
}

let max: Int
if a > b {
max = a
} else {
max = b
}
``````

``````(<CONDITION>) ? <TRUE VALUE> : <FALSE VALUE>
``````

``````let a = 5
let b = 10

let min = a < b ? a : b
let max = a > b ? a : 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`.

### 迷你练习

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 named `answer` and use a ternary condition to set it equal to the result you print out for the same cases in the above exercise. Then print out `answer`.

## 循环

### 徘徊

A `while` loop repeats a block of code while a condition is true. You create a `while` 环形 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 `如果` statements, `while` loops introduce a scope.

The simplest `while` 环形 takes this form:

``````while true {  }
``````

This `while` 环形 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 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` 环形 is called the 重复循环. It differs from the `while` 环形 in that the condition is evaluated 在最后 of the loop rather than at the beginning. You construct a `repeat-while` 环形 like this:

``````repeat {
<LOOP CODE>
} while <CONDITION>
``````

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

``````sum = 1

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

Consider the following `while` loop:

``````sum = 1

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

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

``````sum = 1

repeat {
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! The value of `sum` will equal `1` because the loop won’t execute any iterations.

In the case of the `repeat-while` loop, `sum` will equal `3` because the loop executes once.

### 脱离循环

Sometimes you want to break out of a loop early. You can do this using the `break` statement, which immediately stops the loop’s execution 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` 环形 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 `repeat-while` loop. Inside the loop, set `roll` equal to `Int.random(in: 0...5)` 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.

## 挑战

### 挑战1：找到错误

``````let firstName = "Matt"

if firstName == "Matt" {
let lastName = "Galloway"
} else if firstName == "Ray" {
let lastName = "Wenderlich"
}
let fullName = firstName + " " + lastName
``````

### 挑战2：布尔挑战

In each of the following statements, what is the value of the Boolean `answer` constant?

``````let answer = true && true
let answer = false || false
let answer = (true && 1 != 2) || (4 > 3 && 100 < 1)
let answer = ((10 / 2) > 3) && ((10 % 2) == 0)
``````

### 挑战3：蛇和梯子

Create a constant called `currentPosition` which you can set to whatever position between 1 and 20 which you like. Then create a constant called `diceRoll` which you can set to whatever roll of the dice you want. Finally, calculate the final position taking into account the ladders and snakes, calling it `nextPosition`.

### 挑战4：一个月的天数

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.

## 关键点

• You use the Boolean data type `Bool` to represent true and false.
• 比较运算符，所有这些都返回布尔，是： • You can use Boolean logic (`&&` and `||`) to combine comparison conditions.
• You use `如果` statements to make simple decisions based on a condition.
• You use `else` and `else-if` within an `如果` 陈述 to extend the decision-making beyond a single condition.
• 短路确保仅评估布尔表达式的最小所需部分。
• You can use the ternary operator `(a ? b : c)` in place of simple `如果` statements.
• 变量和常量属于某个范围，超出您无法使用它们的范围。范围继承父母的可见变量和常量。
• `while` 循环允许您多次执行某项任务，直到满足条件。
• `repeat` 循环总是至少执行一次循环。
• The `break` 陈述 lets you break out of a loop.

© 2021 Razeware LLC