★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★ ➤微信公众号:山青咏芝(shanqingyongzhi) ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/) ➤GitHub地址:https://github.com/strengthen/LeetCode ➤原文地址:https://www.cnblogs.com/strengthen/p/9726471.html ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。 ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创! ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
热烈欢迎,请直接点击!!!
进入博主App Store主页,下载使用各个作品!!!
注:博主将坚持每月上线一个新app!!!
Swift提供了各种控制流语句。其中包括while 多次执行任务的循环。if ,,guard 和switch 语句根据特定条件执行不同的代码分支;和诸如和的语句break ,continue 以将执行流转移到代码中的另一点。
Swift还提供了for -in 循环,使您可以轻松地遍历数组,字典,范围,字符串和其他序列。
Swift的switch 语句比许多类似C的语言中的语句要强大得多。案例可以匹配许多不同的模式,包括间隔匹配,元组和强制转换为特定类型。switch 案例中的匹配值可以绑定到要在案例主体中使用的临时常量或变量,并且复杂的匹配条件可以用where 每种案例的子句来表示。
循环内
您可以使用for -in 循环遍历序列,例如数组中的项目,数字范围或字符串中的字符。
本示例使用for -in 循环遍历数组中的项目:
- let names = ["Anna", "Alex", "Brian", "Jack"]
- for name in names {
- print("Hello, \(name)!")
- }
- // Hello, Anna!
- // Hello, Alex!
- // Hello, Brian!
- // Hello, Jack!
您还可以遍历字典以访问其键值对。迭代字典时,字典中的每个项目都作为元组返回,并且您可以将元组的成员分解为显式命名的常量,以在-循环的主体中使用。在下面的代码示例中,字典的键被分解为常量,而字典的值被分解为常量。(key, value) (key, value) for in animalName legCount
- let numberOfLegs = ["spider": 8, "ant": 6, "cat": 4]
- for (animalName, legCount) in numberOfLegs {
- print("\(animalName)s have \(legCount) legs")
- }
- // cats have 4 legs
- // ants have 6 legs
- // spiders have 8 legs
a的内容Dictionary 本质上是无序的,对其进行迭代并不能保证它们的检索顺序。特别是,您将项目插入Dictionary 的顺序并没有定义它们的迭代顺序。有关数组和字典的更多信息,请参见Collection Types。
您还可以使用for -in 具有数字范围的循环。本示例在五倍表中打印前几个条目:
- for index in 1...5 {
- print("\(index) times 5 is \(index * 5)")
- }
- // 1 times 5 is 5
- // 2 times 5 is 10
- // 3 times 5 is 15
- // 4 times 5 is 20
- // 5 times 5 is 25
如使用封闭范围运算符()所示,要迭代的序列的范围是从1 到的一个数字5 范围(含... )。的值index 设置为范围(1 )中的第一个数字,并执行循环内的语句。在这种情况下,循环仅包含一个语句,该语句从5倍表中打印出的当前值index 。执行该语句后,的值将index 更新为包含范围(2 )中的第二个值,然后print(_:separator:terminator:) 再次调用该函数。此过程一直持续到到达范围的终点为止。
在上面的示例中,index 是一个常数,该常数的值在循环的每次迭代开始时自动设置。因此,index 不必在使用前声明它。只需将其包含在循环声明中即可隐式声明它,而无需let 声明关键字。
如果不需要序列中的每个值,则可以使用下划线代替变量名来忽略这些值。
- let base = 3
- let power = 10
- var answer = 1
- for _ in 1...power {
- answer *= base
- }
- print("\(base) to the power of \(power) is \(answer)")
- // Prints "3 to the power of 10 is 59049"
上面的示例将一个数字的值计算为另一个数字的幂(在这种情况下,3 为的幂10 )。它使用以开头和结尾的封闭范围,将起始值1 (即3 的幂0 )乘以3 10倍。对于此计算,不需要每次通过循环都使用单独的计数器值-代码只需按正确的次数执行循环即可。下划线字符()代替循环变量会导致各个值被忽略,并且在每次循环迭代时都无法访问当前值。1 10 _
在某些情况下,您可能不想使用封闭范围,包括两个端点。考虑在表盘上每分钟绘制刻度线。您60 要从0 分钟开始绘制刻度线。使用半开范围运算符(..< )包括下限,但不包括上限。有关范围的更多信息,请参见范围运算符。
- let minutes = 60
- for tickMark in 0..<minutes {
- // render the tick mark each minute (60 times)
- }
有些用户可能希望其UI中的刻度线更少。他们可能更喜欢每5 分钟获得1分。使用此stride(from:to:by:) 功能可以跳过不需要的标记。
- let minuteInterval = 5
- for tickMark in stride(from: 0, to: minutes, by: minuteInterval) {
- // render the tick mark every 5 minutes (0, 5, 10, 15 ... 45, 50, 55)
- }
也可以使用以下范围来提供封闭范围stride(from:through:by:) :
- let hours = 12
- let hourInterval = 3
- for tickMark in stride(from: 3, through: hours, by: hourInterval) {
- // render the tick mark every 3 hours (3, 6, 9, 12)
- }
While循环
甲while 循环执行一组语句,直到条件变为false 。当第一次迭代开始之前不知道迭代次数时,最好使用此类循环。Swift提供两种while 循环:
-
while 每次循环执行时都会评估其条件。
-
repeat -while 在每次循环结束时评估其条件。
尽管
一个while 循环开始通过评估一个条件。如果条件是true ,则重复一组语句,直到条件变为为止false 。
这是while 循环的一般形式:
- while condition {
- statements
- }
这个例子玩一个简单的蛇和 梯@@子 游戏(又称滑梯和 梯@@子 ):
游戏规则如下:
- 木板有25个正方形,目标是在25个正方形上或超出正方形。
- 玩家的起始方块为“零方块”,位于棋盘左下角。
- 每转一圈,您将滚动一个六边形的骰子,并按照上面虚线箭头指示的水平路径移动该正方形数。
- 如果您的转弯在 梯@@子 的底部结束,那么您将向上移动该 梯@@子 。
- 如果转弯结束于蛇的头部,则将其向下移动。
游戏板由一组Int 值表示。它的大小基于一个称为的常数finalSquare ,该常数用于初始化数组,并在示例中的稍后部分检查是否有获胜条件。因为玩家从棋盘上开始,在“零平方”上,所以棋盘被初始化为26个零Int 值,而不是25个零值。
- let finalSquare = 25
- var board = [Int](repeating: 0, count: finalSquare + 1)
然后将一些正方形设置为对蛇和 梯@@子 具有更特定的值。带有梯形底脚的正方形的正数可以使您上板,而带有蛇形头的正方形的负数可以将您下移到板上。
- board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
- board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
方3含有 梯@@子 的底部的是移动你到平方11.为了表示这一点,board[03] 是等于+08 ,这相当于一个整数值8 (之间的差3 和11 )。为了对齐值和语句,一元加运算符(+i )与一元减运算符(-i )显式结合使用,并且将小于10 零的数字填充为零。(两种样式技术都不是绝对必要的,但是它们会导致代码更整洁。)
- var square = 0
- var diceRoll = 0
- while square < finalSquare {
- // roll the dice
- diceRoll += 1
- if diceRoll == 7 { diceRoll = 1 }
- // move by the rolled amount
- square += diceRoll
- if square < board.count {
- // if we're still on the board, move up or down for a snake or a ladder
- square += board[square]
- }
- }
- print("Game over!")
上面的示例使用一种非常简单的方法来掷骰子。而不是生成随机数,而是从diceRoll 值开始0 。每次通过while 循环时,diceRoll 将其递增1,然后检查其是否变得太大。每当此返回值相等时7 ,骰子掷骰就变得太大,并重置为1 。其结果是序列diceRoll 值,这总是1 ,2 ,3 ,4 ,5 ,6 ,1 ,2 等。
掷骰子后,玩家向前移动diceRoll 方块。掷骰子可能会将玩家移至25号方格之外,这种情况下游戏结束了。为了应对这种情况,代码检查square 是否小于board 数组的count 属性。如果square 有效,则将存储的值board[square] 添加到当前square 值,以使播放器在任何 梯@@子 或蛇上上下移动。
笔记
如果未执行此检查,则board[square] 可能尝试访问board 数组范围之外的值,这将触发运行时错误。
然后,当前while 循环执行结束,并检查循环的条件以查看是否应再次执行循环。如果玩家移动到或超过平方数25 ,则循环条件评估为false ,游戏结束。
一个while 循环是在这种情况下,适当的,因为游戏的长度是不是在开始明确while 循环。而是执行循环,直到满足特定条件为止。
重复时
while 循环的另一种形式repeat --while 循环,在考虑循环条件之前,会先执行一次循环循环。然后,它将继续重复循环,直到条件为为止false 。
笔记
本repeat -while 环斯威夫特类似于一个do -while 循环其他语言。
这是repeat -while 循环的一般形式:
- repeat {
- statements
- } while condition
这又是蛇和 梯@@子 的例子,写成repeat -while 循环而不是while 循环。的值finalSquare ,board ,square ,和diceRoll 以完全相同的方式初始化为一个while 循环。
- let finalSquare = 25
- var board = [Int](repeating: 0, count: finalSquare + 1)
- board[03] = +08; board[06] = +11; board[09] = +09; board[10] = +02
- board[14] = -10; board[19] = -11; board[22] = -02; board[24] = -08
- var square = 0
- var diceRoll = 0
在此版本的游戏中,循环中的第一个动作是检查 梯@@子 或蛇。棋盘上没有 梯@@子 可以使玩家直奔25平方,因此不可能通过爬 梯@@子 来赢得比赛。因此,作为循环中的第一个动作,检查蛇或 梯@@子 是安全的。
在游戏开始时,玩家处于“零平方”。board[0] 总是相等0 ,没有效果。
- repeat {
- // move up or down for a snake or ladder
- square += board[square]
- // roll the dice
- diceRoll += 1
- if diceRoll == 7 { diceRoll = 1 }
- // move by the rolled amount
- square += diceRoll
- } while square < finalSquare
- print("Game over!")
代码检查完蛇和 梯@@子 后,掷骰子,玩家向前移动diceRoll 方块。然后,当前循环执行结束。
循环的条件()与以前相同,但是这次直到循环的第一次运行结束时才进行评估。-循环的结构比上一个示例中的循环更适合此游戏。在上面的-循环中,总是在循环的条件确认仍然在板上后立即执行。此行为消除了前面介绍的游戏循环版中看到的数组边界检查的需要。while square < finalSquare repeat while while repeat while square += board[square] while square while
条件语句
根据特定条件执行不同的代码段通常很有用。您可能想在发生错误时运行额外的一段代码,或者在值变得太大或太低时显示一条消息。为此,您需要将部分代码设为条件。
Swift提供了两种向代码中添加条件分支的方法:if 语句和switch 语句。通常,您使用该if 语句评估只有少数可能结果的简单条件。该switch 语句更适合于具有多个可能排列的更复杂条件,并且在模式匹配可以帮助选择合适的代码分支来执行的情况下很有用。
如果
以最简单的形式,该if 语句只有一个if 条件。仅当条件为时,它才执行一组语句true 。
- var temperatureInFahrenheit = 30
- if temperatureInFahrenheit <= 32 {
- print("It's very cold. Consider wearing a scarf.")
- }
- // Prints "It's very cold. Consider wearing a scarf."
上面的示例检查温度是否小于或等于32华氏度(水的冰点)。如果是,则会打印一条消息。否则,将不打印任何消息,并且在if 语句的右大括号之后继续执行代码。
对于条件为的情况,该if 语句可以提供另一组语句,称为else子句。这些语句由关键字指示。if false else
- temperatureInFahrenheit = 40
- if temperatureInFahrenheit <= 32 {
- print("It's very cold. Consider wearing a scarf.")
- } else {
- print("It's not that cold. Wear a t-shirt.")
- }
- // Prints "It's not that cold. Wear a t-shirt."
这两个分支之一始终被执行。由于温度升高到40 华氏度,因此不再足够寒冷以致建议戴围巾,于是else 触发了分支。
您可以将多个if 语句链接在一起以考虑其他子句。
- temperatureInFahrenheit = 90
- if temperatureInFahrenheit <= 32 {
- print("It's very cold. Consider wearing a scarf.")
- } else if temperatureInFahrenheit >= 86 {
- print("It's really warm. Don't forget to wear sunscreen.")
- } else {
- print("It's not that cold. Wear a t-shirt.")
- }
- // Prints "It's really warm. Don't forget to wear sunscreen."
在这里,if 添加了一条额外的声明以应对特别温暖的温度。最后的else 子句仍然保留,并且它会在温度既不高又不太冷的情况下显示响应。
else 但是,final子句是可选的,如果不需要完整的条件集,则可以将其排除。
- temperatureInFahrenheit = 72
- if temperatureInFahrenheit <= 32 {
- print("It's very cold. Consider wearing a scarf.")
- } else if temperatureInFahrenheit >= 86 {
- print("It's really warm. Don't forget to wear sunscreen.")
- }
由于温度既不太冷也不太热,无法触发if 或条件,因此不会打印任何消息。else if
转变
一条switch 语句考虑一个值,并将其与几种可能的匹配模式进行比较。然后,它根据成功匹配的第一个模式执行适当的代码块。一个switch 语句提供的另一种if 用于应对多种潜在状态的语句。
switch 语句以最简单的形式将一个值与一个或多个相同类型的值进行比较。
- switch some value to consider {
- case value 1:
- respond to value 1
- case value 2,
- value 3:
- respond to value 2 or 3
- default:
- otherwise, do something else
- }
每个switch 语句都包含多种可能的情况,每种情况都以case 关键字开头。除了与特定值进行比较之外,Swift还为每种情况提供了几种方法来指定更复杂的匹配模式。这些选项将在本章后面介绍。
就像if 语句的主体一样,每个语句case 都是代码执行的单独分支。该switch 语句确定应选择哪个分支。此过程称为打开要考虑的值。
每个switch 声明都必须详尽无遗。也就是说,所考虑类型的每个可能值都必须与其中一种switch 情况匹配。如果不合适为每个可能的值都提供一个大小写,则可以定义一个默认大小写以覆盖所有未明确寻址的值。此默认情况由default 关键字指示,并且必须始终显示在最后。
本示例使用一条switch 语句来考虑一个名为someCharacter :的小写字符:
- let someCharacter: Character = "z"
- switch someCharacter {
- case "a":
- print("The first letter of the alphabet")
- case "z":
- print("The last letter of the alphabet")
- default:
- print("Some other character")
- }
- // Prints "The last letter of the alphabet"
该switch 语句的第一种情况相匹配的英文字母,第一个字母a ,它的第二种情况下的最后一个字母匹配,z 。因为switch 必须为每一个可能的字符的情况下,不只是每一个字母,这个switch 语句使用default 情况,以配合以外所有的字符a 和z 。该规定确保该switch 陈述是详尽无遗的。
没有隐式掉线
与switch C和Objective-C中的switch 语句相比,Swift中的语句不会掉入每种情况的底部,默认情况下不会进入下一种情况。而是,在switch 第一个匹配的switch 情况完成后,整个语句将立即完成执行,而无需显式break 语句。这使得该switch 语句比C语言中的语句更安全,更易于使用,并且避免switch 了错误地执行多个情况。
笔记
尽管break 在Swift中不是必需的,但是您可以使用break 语句来匹配和忽略特定的情况,或者在该情况完成执行之前中断匹配的情况。有关详细信息,请参见在Switch语句中中断。
每个案例的主体必须包含至少一个可执行语句。编写以下代码是无效的,因为第一种情况为空:
- let anotherCharacter: Character = "a"
- switch anotherCharacter {
- case "a": // Invalid, the case has an empty body
- case "A":
- print("The letter A")
- default:
- print("Not the letter A")
- }
- // This will report a compile-time error.
与switch C中的语句不同,此switch 语句与"a" 和都不匹配"A" 。而是报告不包含任何可执行语句的编译时错误。这种方法避免了从一个案例到另一个案例的意外失败,并使意图更清晰的更安全的代码成为可能。case "a":
为了使switch 与匹配二者的单一情况下"a" 和"A" ,这两个值组合成的化合物的情况下,用逗号分隔的值。
- let anotherCharacter: Character = "a"
- switch anotherCharacter {
- case "a", "A":
- print("The letter A")
- default:
- print("Not the letter A")
- }
- // Prints "The letter A"
为了便于阅读,还可以将多行案例写在多行上。有关复合案例的更多信息,请参见复合案例。
间隔匹配
switch 可以检查案例中的值是否包含在间隔中。本示例使用数字间隔为任意大小的数字提供自然语言计数:
- let approximateCount = 62
- let countedThings = "moons orbiting Saturn"
- let naturalCount: String
- switch approximateCount {
- case 0:
- naturalCount = "no"
- case 1..<5:
- naturalCount = "a few"
- case 5..<12:
- naturalCount = "several"
- case 12..<100:
- naturalCount = "dozens of"
- case 100..<1000:
- naturalCount = "hundreds of"
- default:
- naturalCount = "many"
- }
- print("There are \(naturalCount) \(countedThings).")
- // Prints "There are dozens of moons orbiting Saturn."
在上面的示例中,approximateCount 在一条switch 语句中求值。每个case 比较该值与一个数字或间隔。因为值的approximateCount 落差介于12到100之间,naturalCount 所以将为其分配值,并且执行从语句中转移出来。"dozens of" switch
元组
您可以使用元组在同switch 一条语句中测试多个值。元组的每个元素都可以针对不同的值或值的间隔进行测试。或者,使用下划线字符(_ ),也称为通配符模式,以匹配任何可能的值。
下面的示例采用一个(x,y)点,表示为type的简单元组,并将其分类在该示例之后的图上。(Int, Int)
- let somePoint = (1, 1)
- switch somePoint {
- case (0, 0):
- print("\(somePoint) is at the origin")
- case (_, 0):
- print("\(somePoint) is on the x-axis")
- case (0, _):
- print("\(somePoint) is on the y-axis")
- case (-2...2, -2...2):
- print("\(somePoint) is inside the box")
- default:
- print("\(somePoint) is outside of the box")
- }
- // Prints "(1, 1) is inside the box"
该switch 语句确定该点是在原点(0,0)上,在红色x轴上,在橙色y轴上,在以原点为中心的蓝色4 x 4框内还是在框外。
与C不同,Swift允许多种switch 情况考虑相同的一个或多个值。实际上,在此示例中,点(0,0)可以匹配所有四种情况。但是,如果可能有多个匹配项,则始终使用第一个匹配情况。点(0,0)将首先匹配,因此所有其他匹配情况将被忽略。case (0, 0)
价值绑定
一个switch 情况下,可以将其命名为临时常量或变量,在案件的身体使用相匹配的一个或多个值。这种行为称为值绑定,因为值绑定到案例主体内的临时常量或变量。
下面的示例获取一个(x,y)点,表示为type的元组,并将其分类在下面的图上:(Int, Int)
- let anotherPoint = (2, 0)
- switch anotherPoint {
- case (let x, 0):
- print("on the x-axis with an x value of \(x)")
- case (0, let y):
- print("on the y-axis with a y value of \(y)")
- case let (x, y):
- print("somewhere else at (\(x), \(y))")
- }
- // Prints "on the x-axis with an x value of 2"
该switch 语句确定该点是在红色的x轴上,在橙色的y轴上还是在其他位置(都不在两个轴上)。
这3种switch 情况声明了占位符常量x 和y ,它们临时取自的一个或两个元组值anotherPoint 。第一种情况匹配任何值为的点,并将该点的值分配给临时常量。类似地,第二种情况匹配任何值为的点,并将该点的值分配给临时常量。case (let x, 0) y 0 x x case (0, let y) x 0 y y
声明临时常量后,可以在案例的代码块中使用它们。在这里,它们用于打印点的分类。
这switch 句话没有default 理由。最后一种情况,声明了两个可以匹配任何值的占位符常量的元组。因为始终是两个值的元组,所以该情况与所有可能的剩余值匹配,并且不需要使情况穷举的情况。case let (x, y) anotherPoint default switch
在哪里
一个switch 情况下可以使用where 子句来检查附加条件。
下面的示例在下图上对(x,y)点进行了分类:
- let yetAnotherPoint = (1, -1)
- switch yetAnotherPoint {
- case let (x, y) where x == y:
- print("(\(x), \(y)) is on the line x == y")
- case let (x, y) where x == -y:
- print("(\(x), \(y)) is on the line x == -y")
- case let (x, y):
- print("(\(x), \(y)
|
请发表评论