首页 iOS.& Swift Books Swift学徒

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

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

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

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

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

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.

布尔运营商

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

在Swift中,你使用这件事 平等运营商, which is denoted by ==:

let doesOneEqualTwo = (1 == 2)

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

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

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

还有一个运算符,可让您测试值是否小于 或者 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 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 错误的.

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

括号歧义表达式。首次SWIFT评估括号内的子表达式,然后它评估完整表达式,按照以下步骤:

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

笔记:您将在第9章“Strings”中了解有关字符串平等的更多信息。当字符串包含特殊字符时,存在一些有趣的事情。

切换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.

笔记: The toggle() 这里 is a call to a 功能。在第5章“函数”中,您将在第12章“函数”中看到更多关于这些信息,以及它们在第12章“方法”中的类型。

迷你练习

  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语句

控制程序流程的第一种和最常用方式是通过使用 如果 statement,这允许该计划仅做某事 如果 某种情况是真的。例如,考虑以下内容:

如果 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.

封装变量

如果 陈述介绍了一个新的概念 范围,这是一种通过使用括号封装变量的方法。想象一下,您想计算为客户收费的费用。这是你所做的交易:

每小时赚取25美元,每小时均为每小时25美元,每小时50美元。

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

var hoursWorked = 45

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

print(price)

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

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

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.

三元条件运营商

现在我想介绍一个新的运营商,其中一个没有看到第2章“类型&操作“。它被称为 三元条件运营商 and it’s related to 如果 statements.

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.

我相信你会同意这更简单!这是一个有用的运营商,您会定期发现自己。

笔记: Because finding the greater or smaller of two numbers is such a common operation, the Swift 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.

迷你练习

  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.

循环

循环 are Swift’s way of executing code multiple times. In this section, you’ll learn about one type of loop: the while loop. If you know another programming language, you’ll find the concepts and maybe even the syntax to be familiar.

徘徊

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:蛇和梯子

想象一下你正在玩一场蛇游戏&从位置1到位20的梯子。在它上面,梯子在3和7的位置,分别带到15和12。然后,位置11和17的蛇分别带到2和9。

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.

挑战5:两个下一个力量

给定一个数字,确定上面的两个或等于该数字的下一个功率。

挑战6:三角数

给定一个数字,打印该深度的三角形数量。您可以在此处进行三角数字的复述: //en.wikipedia.org/wiki/Triangular_number

挑战7:斐波纳契

计算n'th fibonacci号码。请记住,FibonAcci Numbers以1和1启动其序列,然后序列中的后续数字等于添加在一起的前两个值。您可以在这里进行修复: //en.wikipedia.org/wiki/Fibonacci_number

挑战8:制作一个循环

使用循环打印出给定系数的次数表。

挑战9:骰子卷桌

打印一个表,显示组合的数量,以便在2到12给给定的2个六面骰子卷中创建每个数字。您不应该使用公式,而是通过考虑每个可能的骰子卷来详尽地计算组合数量。

关键点

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

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

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

© 2021 Razeware LLC