Swift流程控制之循环语句和判断语句详解剖析.docx
- 文档编号:25191924
- 上传时间:2023-06-06
- 格式:DOCX
- 页数:27
- 大小:227.58KB
Swift流程控制之循环语句和判断语句详解剖析.docx
《Swift流程控制之循环语句和判断语句详解剖析.docx》由会员分享,可在线阅读,更多相关《Swift流程控制之循环语句和判断语句详解剖析.docx(27页珍藏版)》请在冰豆网上搜索。
Swift流程控制之循环语句和判断语句详解剖析
Swift流程控制之循环语句和判断语句详解
Swift提供了所有c类语言的控制流结构。
包括for和while循环来执行一个任务多次;if和switch语句来执行确定的条件下不同的分支的代码;break和continue关键字能将运行流程转到你代码的另一个点上。
除了C语言传统的for-condition-increment循环,Swift加入了for-in循环,能更加容易的遍历arrays,dictionaries,ranges,strings等其他序列类型。
Swift的switch语句也比C语言的要强大很多。
Swift中switch语句的case语句不会“掉入”下一个case,避免了c语言忘记写break语句产生的错误。
case可以匹配许多不同的模式,包括范围匹配,元组匹配或者抛给指定的类型。
匹配值在一个case条件下可以绑定到临时常量或变量,可以在case的代码块中使用,复杂匹配条件下可以表示为每一个case的条件
一、ForLoops-For循环
for循环用来多次执行一组语句,Swift提供了两种形式:
1.for-in执行范围,序列,集合或级数等每一项中的一组语句
2.for-condition-increment执行一组语句直到确定的条件出现,通常在每一个循环结束前递增一个计数
For-In循环
使用for-in来遍历集合中的项目,比如数组的范围,排列中的项或者字符串中的字符。
下面的例子打印了表中的5个元素
复制代码代码如下:
forindexin1...5{
println("\(index)times5is\(index*5)")
}
//1times5is5
//2times5is10
//3times5is15
//4times5is20
//5times5is25
例子中被迭代集合的项是一个封闭范围内从1到5的数字,就是上面标识为封闭范围操作符的(...)。
Index的值被设为第一个数据的范围
(1),然后执行循环中的语句。
在本例中,循环只包含了一句话,根据index现有的值打印5次乘法表的一个结果。
当执行完语句之后,index的值被更新为范围中的第二个值,然后再次调用println函数。
这个操作会一直持续,直到范围的终点。
在上面的例子中,index是一个常量,它的值在每次迭代的开始时自动初始化,使用前不会被声明,就是简单的将其隐性声明纳入循环的声明,不需要使用let来声明关键字。
复制代码代码如下:
NOTE:
Index常量仅仅存在于循环的范围内。
如果你想要在循环之后得到index的值,或者想要使用index的值作为变量,你必须在循环之前声明它。
如果不需要范围的值,可以用下划线替代变量名来忽略这些值:
复制代码代码如下:
letbase=3
letpower=10
varanswer=1
for_in1...power{
answer*=base
}
println("\(base)tothepowerof\(power)is\(answer)")
//prints"3tothepowerof10is59049"
例子中计算两数相乘(在本例中,3乘以10)。
乘法初始值为1,每次乘3,乘10次,使用半封闭循环从0到9。
这个计算不需要通过循环来知道每个计数器的值--仅仅只需要执行正确的循环次数。
下划线操作符_(用于替代循环变量)将忽略掉个体值,并且在每一次循环迭代期间不给现有的变量提供访问。
使用for-in循环来迭代出array中的每一个项:
复制代码代码如下:
letnames=["Anna","Alex","Brian","Jack"]
fornameinnames{
println("Hello,\(name)!
")
}
//Hello,Anna!
//Hello,Alex!
//Hello,Brian!
//Hello,Jack!
同样可以迭代字典来访问其中的键值对。
当迭代字典时里面的每一个项都以(key,value)元组的形式来返回,你可以在for-in的循环体中分解(key,value)元组的成员,把成员作为显性命名的常量来使用。
下面例子,字典的key被分解为animalName的常量,字典的值被分解名为legCount的常量:
复制代码代码如下:
letnumberOfLegs=["spider":
8,"ant":
6,"cat":
4]
for(animalName,legCount)innumberOfLegs{
println("\(animalName)shave\(legCount)legs")
}
//spidershave8legs
//antshave6legs
//catshave4legs
Dictionary中的项的迭代顺序可能跟它们插入时的顺序不一样。
因为Dictionary中的内容本质上是无序的,所以迭代它们不能保证检索时的顺序。
更多关于排列和字典的内容详见CollectionTypes章节。
除了排列和字典,for-in循环还能迭代字符串中的Character(字符):
复制代码代码如下:
forcharacterin"Hello"{
println(character)
}
//H
//e
//l
//l
//o
For-Condition-IncrementFor-条件-递增
除了for-in循环,Swift还支持传统C语言按条件递增的for循环
复制代码代码如下:
forvarindex=0;index<3;++index{
println("indexis\(index)")
}
//indexis0
//indexis1
//indexis2
这是常用的形式:
复制代码代码如下:
for
}
封号把循环定义隔为了三个部分,跟C语言一样。
然而与C不同的是,Swift不需要用括号把“初始化;条件;增量”的代码块包起来。
循环按照下面流程执行:
1.当循环第一次进入,initializationexpression(初始化表达式)计算一次,设置好循环所需的常量或者变量。
2.计算conditionexpression(条件表达式)。
如果计算结果为false(假),循环终止,并继续执行for循环尾括号(})后面的代码。
如果结果为(true)真,则执行循环体大括号内的代码。
3.在所有的语句执行完后,计算incrementexpression(增量表达式)。
计数器可能递增或递减,也可能根据语句执行的结果将初始化变量设为新的值。
计算完增量表达式返回到第2步,条件表达式再次被计算。
上面描述的循环体的形式和执行过程可以简单的等同于:
复制代码代码如下:
while
}
常量和变量在初始化表达式中的声明(比如varindex=0)只在for循环自己内部有效。
如果需要知道index最终的值,必须在循环开始前声明index:
复制代码代码如下:
varindex:
Int
forindex=0;index<3;++index{
println("indexis\(index)")
}
//indexis0
//indexis1
//indexis2
println("Theloopstatementswereexecuted\(index)times")
//prints"Theloopstatementswereexecuted3times"
注意,循环完成后index最终的值是3,不是2。
最后一次执行增量表达式调用了++index,把index设为3,使得index<3等于false,循环结束。
二、WhileLoops-While循环
while循环在条件变为false前执行一组语句,这类循环最好用在第一个迭代开始前并不知道迭代器的数字的时候。
Swift提供了两种while循环:
1.while在每次通过循环的开头计算条件
2.do-while在每次通过循环的结尾计算条件
while循环
一个while循环开始于计算单个的条件,如果条件为true,一组语句将重复直到条件变为false。
这是常见的while形式:
复制代码代码如下:
while
}
比如,玩这个叫SnakesandLadders的游戏(或ChutesandLadders):
游戏的规则是这样的:
1.板子上有25个矩形,然后目标是到达或超越25号方块。
2.每一轮,你先摇六面骰子,然后按照水平方向的虚线箭头移动到对应数字的方块上。
3.如果走完落在梯子的底部,你可以爬上梯子。
4.如果走完落在蛇的头部,你可以走到那条蛇的尾部。
这个游戏板由一个Int型数组展示出来。
它的大小基于finalSquare常量,该常量用来初始化数组并在之后检查胜利条件。
游戏板初始化为26个值为0的Int型数据,不是25个(分别位于0至25的索引):
复制代码代码如下:
letfinalSquare=25
varboard=Int
一些方块给蛇与梯子设有具体的值。
游戏板里,你能在有方块有梯子脚的地方向上移动正数,而有蛇头的地方你只能向下移动负数:
复制代码代码如下:
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就用0替代,这样所板上的定义就对齐了。
(风格调整不是必须的,但代码简洁很有必要)
玩家开始于方块0,就在游戏板左下角的外面。
第一下投骰是把玩家带到游戏版里面:
复制代码代码如下:
varsquare=0
vardiceRoll=0
whilesquare //rollthedice if++diceRoll==7{diceRoll=1} //movebytherolledamount square+=diceRoll ifsquare //ifwe'restillontheboard,moveupordownforasnakeoraladder square+=board[square] } } println("Gameover! ") 这个例子很简单的模拟了投骰子。 用随机数的生成器来替代,diceRoll从0开始。 每一个while循环,diceRoll通过自加运算符(++i)递增,然后检查是否过大。 ++diceRoll的返回值等于diceRoll自加以后的值。 如果返回值等于7,骰子值则过大,重设为1。 这样diceRoll的值会一直是1,2,3,4,5,6,1,2等等。 在摇骰子后,玩家根据diceRoll移动方块。 有可能骰子的数会让玩家超过方块25,这样就算游戏结束。 为了描述这个场景,代码在向board[square]添加值以前先检查square的值是否少于board数组的count属性,如果是则根据现有的square值将玩家上移或下移到相应梯子或蛇。 如果不执行这个检查,board[square]会可能尝试取得board数组界限外的值,导致越界。 如果square现在等于26,代码将尝试检查board[26],这个值超过了数组限制。 现有的While循环执行到最后,会检查循环条件看循环是否会再次执行。 如果玩家已经移动或者方块超过25,循环条件会计算为false,游戏结束。 在这个例子中使用While循环是比较合适的,因为游戏的长度在循环的开头不明确,让循环一直执行直到特定的满足条件出现。 Do-While循环 While循环的另一个形式是do-while,在考虑循环条件前先执行一次整个循环体,然后再继续重复循环直到条件为false。 下面是do-while的常见形式: 复制代码代码如下: do{ }while 再来看看SnakesandLadders的例子,用do-while而不是while来实现。 finalSquare,board,square,和diceRoll都用相同的方式初始化: 复制代码代码如下: letfinalSquare=25 varboard=Int[](count: finalSquare+1,repeatedValue: 0) board[03]=+08;board[06]=+11;board[09]=+09;board[10]=+02 board[14]=-10;board[19]=-11;board[22]=-02;board[24]=-08 varsquare=0 vardiceRoll=0 在这个版本的游戏中,循环中第一个操作是检查一个梯子或蛇。 没有梯子能直接把玩家带到方块25,所以不可能只爬一个梯子就赢了。 因此在循环里先检查梯子或蛇会更安全。 游戏的开始,玩家在“方块0”。 board[0]永远等于0,没有别的功能: 复制代码代码如下: do{ //moveupordownforasnakeorladder square+=board[square] //rollthedice if++diceRoll==7{diceRoll=1} //movebytherolledamount square+=diceRoll }whilesquare println("Gameover! ") 在代码检查后,开始摇骰子,玩家通过diceRoll方块向前移动,该循一直环执行到最后。 循环条件(whilesquare do-while循环的结构比while循环更适合本例。 上面do-while中,在循环条件确认square仍旧在游戏板里面后,square+=board[square]会直接进行计算,不必进行数组越界的检查。 三、ConditionalStatements-条件语句 编程中常常根据不同的条件执行不同的代码,你可能会要代码在出错后运行额外的语句,或者当数值越界时展示一个消息。 我们可以用conditional(条件)来实现。 Swift提供两种方式来添加代码的分支,常见的if和switch语句。 显然,用if语句来计算只有少量分支的的条件,而Switch用于更复杂的情况,特别是在模式匹配的时候有助于选择合适的代码分支来执行。 If语句 在下面最简单的例子里,if语句有一个if条件。 所有的语句都只有在if条件为true的情况下才执行: 复制代码代码如下: vartemperatureInFahrenheit=30 iftemperatureInFahrenheit<=32{ println("It'sverycold.Considerwearingascarf.") } //prints"It'sverycold.Considerwearingascarf." 前面的例子检查了温度是否等于32摄氏度。 如果是则打印消息。 否则不打印消息,直接执行if语句大括号后面的代码。 if语句可以提供一个二选一的语句,常见的: elseclause,用于当if条件为false时。 这些语句用else关键字来控制: 复制代码代码如下: temperatureInFahrenheit=40 iftemperatureInFahrenheit<=32{ println("It'sverycold.Considerwearingascarf.") }else{ println("It'snotthatcold.Wearat-shirt.") } //prints"It'snotthatcold.Wearat-shirt." 两个大括号中的一个被执行。 因为温度增加超过了40摄氏度,已经不需要建议去带围巾,所以else分支被触发。 你可以使用多个if语句,像这样增加条件: 复制代码代码如下: temperatureInFahrenheit=90 iftemperatureInFahrenheit<=32{ println("It'sverycold.Considerwearingascarf.") }elseiftemperatureInFahrenheit>=86{ println("It'sreallywarm.Don'tforgettowearsunscreen.") }else{ println("It'snotthatcold.Wearat-shirt.") } //prints"It'sreallywarm.Don'tforgettowearsunscreen." 这里增加的if语句用于应对极端炎热的情况。 最后的else条件保留,打印既不冷也不热的情况。 最后的else条件是可选的,因此如果不需要写完整可以去掉。 复制代码代码如下: temperatureInFahrenheit=72 iftemperatureInFahrenheit<=32{ println("It'sverycold.Considerwearingascarf.") }elseiftemperatureInFahrenheit>=86{ println("It'sreallywarm.Don'tforgettowearsunscreen.") } 在这个例子中,温度既不冷也不热才能触发if或者else条件来打印信息。 Switch语句 Switch语句用一个值来匹配相对应的几个匹配模式。 然后执行相对应的代码块,基于一开始匹配成功的模式。 switch语句提供了应对多种选择情况的处理来替代if语句。 最简单的形式,switch比较一个值对应的一个或者多个相同形式的值: 复制代码代码如下: switchsomevaluetoconsider{ casevalue1: respondtovalue1 casevalue2, value3: respondtovalue2or3 default: otherwise,dosomethingelse } 每个switch语句由多个可能的case(情况)构成,都用标记的case关键字开头。 除了比较对应的值,Swift还为每种case应对更复杂的匹配模式提供了几种方法,后面章节再说。 每一个switch语句都必须exhaustive(详细),并且每一个所考虑类选可能的值都必须匹配switch中的一个case。 如果不能对应到switch中的所有case的值,可以定义个默认的选取器来解决。 选取器用default关键字来表示,必须出现在最后。 下面的例子用switch语句匹配了一个小写字符,someCharacter: 复制代码代码如下: letsomeCharacter: Character="e" switchsomeCharacter{ case"a","e","i","o","u": println("\(someCharacter)isavowel") case"b","c","d","f","g","h","j","k","l","m", "n","p","q","r","s","t","v","w","x","y","z": println("\(someCharacter)isaconsonant") default: println("\(someCharacter)isnotavoweloraconsonant") } //prints"eisavowel" Switch语句第一个case匹配了5个小写的元音字母。 相似地,第二个case匹配所有的辅音小写字母。 case中并不需要写上所有其他的英语字母,所以switch提供了default来匹配其他所有不是元音也不是辅音的情况。 这样的条件保证了switch没有遗漏。 NoImplicitFallthrough-没有隐性掉入 相比C和objective-c中的switch语句,Swift中(如果忘了写break)的switch不会默认的掉落到每个case的下面进入另一个case。 相反,switch语句当第一个遇到的case完成时就完成了它整个的执行,不需要写break。 因此比起C语言,swift的switch更加安全和简单,避免了执行多个case的错误。 NOTE: 如果你需要,仍旧可在case执行完以前跳出来,详见: [BreakinaSwitchStatement]见下面章节 每个case的主干包括只少一个可执行的语句。 下面这样写是无效的,因为第一个case是空的: 复制代码代码如下: letanotherCharacter: Character="a" switchanotherCharacter{ case"a": case"A": println("TheletterA") default: println("NottheletterA") } //thiswillreportacompile-timeerror 不像C语言中的Switch,这里的switch语句不能匹配"a"和"A"。 比如,case"a"会在编译时报错: 没有找到任何可执
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Swift 流程 控制 循环 语句 判断 详解 剖析