Swift开发系列之控制流详解

swift提供类似C语言控制流结构,包含for 和while循环语句,if和switch分支控制语句,除了C中传统for循环语句swift还提供for-in循环语句这种方式更容易迭代数组,字典,一个范围,字符串,和其他序列。


Swift的switch语句比C中的更强大,switch中的case语句执行完不会执行下个case代码块中在case末尾没有break时,case可以去匹配很多数据类型,

包含一个范围,元组,和一个明确值,匹配的值在switch语句中的case绑定一个常量或者变量并且可以在case代码块里使用,并且可以合成匹配条件在case表达式后面加一个where。

For Loops

for循环执行指定次数,有两种格式:

                for-in 执行每项在一个范围,序列,集合,级数。

                for-condition-increment执行循环在条件满足时否则结束循环

For-In

你可以使用for-in迭代集合的每一项,例如一个范围对一个数,数组中的项,或者字符串对字符的迭代。

下面这个例子将在five-times-table打印几个条目。

for index in 1...5{

    printfln("\(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并且执行循环,该循环只包含一个打印 five-times-table index 乘以5的语句,

继续执行循环并且index被修改为2,然后再一次打印,直到index为5循环结束。

在上面的这个例子中index为常量并且自动设置值在每次循环开始,因此不需要定义index在使用它之前,index被隐式定义在定义循环时所以不需要在index前面加let关键字。

注意:

            index常量可以使用仅仅在for循环里面,如果在执行完for循环还想使用index,或者你想把index作为变量,你必须定义index在for循环之前。

如果你不需要一个范围里的每个项,你可以忽略使用下划线在变量名这个位置:

letbase =3

letpower =10

varanswer =1

for_in1...power {

answer *=base

println("\(base) to the power of \(power) is\(answer)")

// prints "3 to the power of 10 is 59049"


这个例子就是做10次循环,而不取1-10这个范围的每个值。

使用for-in对数组进行迭代:

letnames = ["Anna","Alex","Brian","Jack"]

fornameinnames {

println("Hello,\(name)!")

  • }// Hello, Anna!
  • // Hello, Alex!
  • // Hello, Brian!
  • // Hello, Jack!

也可以使用键值对迭代对字典,当字典被迭代每次循环都回返回(key,value)元组。可以分解该元组用定义好的名称常量使用在for-in循环里面。这里,这个

字典的键被分解到了叫animalName常量。值分解到legCount。

letnumberOfLegs = ["spider":8,"ant":6,"cat":4]

for (animalName,legCount)innumberOfLegs {

println("\(animalName)s have \(legCount) legs")

// spiders have 8 legs

// ants have 6 legs

// cats have 4 legs

字典是无序的,在检索字典时不需要指定顺序。

for-in也可以迭代字符串到字符:

forcharacterin"Hello" {

println(character)

  • }// H
  • // e
  • // l
  • // l
  • // o

For-Condition-Increment

除了for-in循环,swift可以支持类似C语言方式的条件递增方式:

forvarindex =0;index <3; ++index {

println("index is\(index)")

  • }// index is 0
  • // index is 1
  • // index is 2

一般循环格式:

  • for initialization; condition; increment {
  •     statements
  • }

分号分隔for循环的3个部分,不像c语言,swift里for不需要花括号,该方式的循环执行流程:

1,首先检查condition是否满足如果满足条件那么进入循环体

2,然后执行increment递增或者递减

3,再检查condition。。。。。。

还有一种简短的循环方式与上面效果一样:

  • initialization
  • while condition {
  •     statements
  •     increment
  • }
常量或者变量定义在循环的初始化该使用范围只能在循环体里面,如果想在循环执行完使用该变量必须初始化变量在循环语句前面。

varindex:Int

forindex =0;index <3; ++index {

println("index is\(index)")

  • }// index is 0
  • // index is 1
  • // index is 2
  • println("The loop statements were executed \(index) times")
  • // prints "The loop statements were executed 3 times"

While Loops

while循环执行直到条件为false结束,适合开始执行循环不知道条件真假,while循环有两种方式:

         while  首先检查循环条件

         do-while 先执行一次然后检查循环条件

While

while开始循环判断单一条件,如果为真那么继续执行,否则跳出循环。

这里有一个简单的while循环语句格式:

  • while condition {
  •     statements
  • }

Do-While

do-while和while不同,它会先执行一次循环体里的代码,然后再检查循环条件,然后一直重复循环直到条件为false.

这里有一个简单的do-while循环语句格式:

  • do {
  •     statements
  • } while condition

Conditional Statements

这是非常有用的去执行指定条件的代码块,你可能去执行一些代码当错误发生时或者显示一条消息当一个值太大或者太小,

你可以在代码使用它。

swift提供两种方式添加条件分支在代码中,if和switch,if主要处理一下可能结果比较少的情况,switch主要处理可能结果比较多的情况。

If

下面有一个简单例子,if只有条件为true时才会执行if里面的代码:

vartemperatureInFahrenheit =30

iftemperatureInFahrenheit <=32 {

println("It's very cold. Consider wearing a scarf.")

  • }// prints "It's very cold. Consider wearing a scarf."
当if条件为false时可以用else去处理情况:

temperatureInFahrenheit =40

iftemperatureInFahrenheit <=32 {

println("It's very cold. Consider wearing a scarf.")

}else {

println("It's not that cold. Wear a t-shirt.")

  • }// prints "It's not that cold. Wear a t-shirt."

也可以包含多个if:

temperatureInFahrenheit =90

iftemperatureInFahrenheit <=32 {

println("It's very cold. Consider wearing a scarf.")

}elseiftemperatureInFahrenheit >= 86 {

println("It's really warm. Don't forget to wear sunscreen.")

}else {

println("It's not that cold. Wear a t-shirt.")

}// prints "It's really warm. Don't forget to wear sunscreen."


Switch

switch可以处理一系列可能的情况,当匹配成功会执行相应的代码块

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还提供一系列更复杂组合比较,这一小节将会介绍。

每个switch 的case代码块都是分开执行,这种方式有点类似if语句块,每个switch都会被穷举,每个可能的值必须是匹配switch其中一个case,如果没有提供合适case,可以定义默认去捕获所有

可能情况不需要指定匹配值,捕获任何可能情况用关键字default,它必须在switch最后。

下面这个例子用switch语句查找小写字符,调用someCharacter函数:

letsomeCharacter:Character = "e"

switchsomeCharacter {

case"a","e","i","o","u":

println("\(someCharacter) is a vowel")

case"b","c","d","f","g","h","j","k","l","m",

"n","p","q","r","s","t","v","w","x","y","z":

println("\(someCharacter) is a consonant")

default:

println("\(someCharacter) is not a vowel or a consonant")

prints "e is a vowel"

这switch第一case首先会匹配5个小写英文字符,第二个case会匹配剩余所有小写英文字符。

这里没有一一去写所有可能情况case,并且提供了default去捕获不是字符,或者常量的情况。这可以确保switch穷举所有情况。

No Implicit Fallthrough

对比C和Objc中的switch,swift中的switch在执行完一个case默认不会落空到下一个case中,反而在switch中没有break语句时执行完一个匹配的case就算完成了。

swift是类型安全并且更容易使用比C语言,并且避免了执行switch语句case时造成更多错误。

注意:

      在执行匹配完一个case之前仍然可以跳出,详细可以看 Break in a Switch Statement

case里面必须包含一条执行语句,下面这个例子是错误的,因为第一个case里什么都没有:

letanotherCharacter:Character = "a"

switchanotherCharacter {

case"a":

case"A":

println("The letter A")

default:

println("Not the letter A")

// this will report a compile-time error

和c语言不像,上面这个例子不会自动去匹配"a"和"A",这会报编译时错误case:"a" 没有包含任何可执行代码,应该避免造成落空到其他case,并且代码要安全和更清晰。

多个匹配值在一个case用逗号分开,如果一行太长了可以写成多行:

  • switch some value to consider {
  • case value 1,
  • value 2:
  •     statements
  • }
注意:

     对于有落空情况在switch case是特殊的,使用关键字fallthrough,可以看Fallthrough。

Range Matching

switch case的值可以检测一个范围,下面这个例子检测一个任何数字的范围:

letcount = 3_000_000_000_000

letcountedThings = "stars in the Milky Way"

varnaturalCount:String

switchcount {

case0:

naturalCount = "no"

case1...3:

naturalCount = "a few"

case4...9:

naturalCount = "several"

case10...99:

naturalCount = "tens of"

case100...999:

naturalCount = "hundreds of"

case1000...999_999:

naturalCount = "thousands of"

default:

naturalCount = "millions and millions of"

println("There are \(naturalCount)\(countedThings).")

// prints "There are millions and millions of stars in the Milky Way."

Tuples

可以在switch中使用元组,元组的么个元素可以测试对不同的值或者一个范围值。也可以是下划线_去匹配任何可能的值。

下面有个例子一个简单元组(Int,Int)是一个点:

letsomePoint = (1,1)

switchsomePoint {

case (0,0):

println("(0, 0) is at the origin"

case (_,0):

println("(\(somePoint.0), 0) is on the x-axis")

case (0,_):

println("(0,\(somePoint.1)) is on the y-axis")

case (-2...2, -2...2):

println("(\(somePoint.0),\(somePoint.1)) is inside the box")

default:

println("(\(somePoint.0),\(somePoint.1)) is outside of the box")

// prints "(1, 1) is inside the box"

Value Bindings

一个switch case值可以和一个常量或者变量绑定,并且可以使用在case代码块里面。

下面有一个例子:

letanotherPoint = (2,0)

switchanotherPoint {

case (letx,0):

println("on the x-axis with an x value of \(x)")

case (0,lety):

println("on the y-axis with a y value of \(y)")

caselet (x,y):

println("somewhere else at (\(x),\(y))")

// prints "on the x-axis with an x value of 2"

Where

在switch里面可以附加使用where检测条件如:

letyetAnotherPoint = (1, -1)

switchyetAnotherPoint {

caselet (x,y)wherex == y:

println("(\(x),\(y)) is on the line x == y")

caselet (x,y)wherex == -y:

println("(\(x),\(y)) is on the line x == -y")

caselet (x,y):

println("(\(x),\(y)) is just some arbitrary point")

// prints "(1, -1) is on the line x == -y"

Control Transfer Statements

控制转换语句可以改变代码执行顺序,从一个代码块到其他代码块,swift有如下几种控制转换语句:

  • continue

  • break

  • fallthrough

  • return

continue ,break,fallthrough下面会介绍,return被介绍在Functions

Continue

continue可以结束当前循环而直接进入下一次循环,下面有一个例子:
let puzzleInput = "great minds think alike"
var puzzleOutput = ""
for character in puzzleInput {
switch character {
case "a" , "e" , "i" , "o" , "u" , " " :
continue
default :
puzzleOutput += character
}
println ( puzzleOutput )
// prints "grtmndsthnklk"
这什么意思自己一看就知道,我就不细翻译,打字累~^~

Break

break可以使用在循环和switch中,在循环中意思是:终止循环,在switch中意思是:跳出switch,当case下什么都不想写时可以写break语句代替。
注意:
     在switch case中不需要写注释而不写可执行代码,这时会有编译时错误,我们因该用break代替。
下面有一个例子:
let numberSymbol : Character = "三" // Simplified Chinese for the number 3
var possibleIntegerValue : Int ?
switch numberSymbol {
case "1" , "١" , "一" , "๑" :
possibleIntegerValue = 1
case "2" , "٢" , "二" , "๒" :
possibleIntegerValue = 2
case "3" , "٣" , "三" , "๓" :
possibleIntegerValue = 3
case "4" , "٤" , "四" , "๔" :
possibleIntegerValue = 4
default :
break
if let integerValue = possibleIntegerValue {
println ( "The integer value of \( numberSymbol ) is \( integerValue ) ." )
else {
println ( "An integer value could not be found for \( numberSymbol ) ." )
/ prints "The integer value of 三 is 3."
这个例子 possibleIntegerValue  是一个可选类型的变量,该可选类型变量possibleIntegerValue 被隐含nil初始化,该可选类型变量最后会和这4个case其中一个绑定,并且default可以处理
其他意外情况但是什么都没有处理使用了break不能什么都不写。

Fallthrough

switch默认情况不会落空到一个case,如果在执行完一个case还想执行下一case那么可以使用fallthrough关键字,下面有一个例子:
let integerToDescribe = 5
var description = "The number \( integerToDescribe ) is"
switch integerToDescribe {
case 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 :
description += " a prime number, and also"
fallthrough
default :
description += " an integer."
}
println ( description )
// prints "The number 5 is a prime number, and also an integer."

注意:

    fallthrough落空时不会检测下一case条件而是直接进入下一个case代码块执行,这c语言的默认情况是一样的.

Labeled Statements

你可以在循环语句里面内嵌一个switch语句或者一个循环语句,然而switch和循环语句里面都可以使用break语句,因此在内嵌结构的语句给循环和switch加标签时很有用对于执行
break语句,这时可以显示要终止那个语句通过标签名。同样continue也是很有用的嵌套循环里面。
一个标签名声明在switch或者while前面用冒号分开,下面就是标签语法形式:
  • label name: while condition {
  •     statements
  • }
  • 下面有一个例子:
  •       
          
    • gameLoop: while square != finalSquare {
    • if ++diceRoll == 7 { diceRoll = 1 }
    • switch square + diceRoll {
    • case finalSquare:
    • // diceRoll will move us to the final square, so the game is over
    • break gameLoop
    • case let newSquare where newSquare > finalSquare:
    • // diceRoll will move us beyond the final square, so roll again
    • continue gameLoop
    • default:
    • // this is a valid move, so find out its effect
    • square += diceRoll
    • square += board[square]
    • }
    • }
    • println("Game over!")
    标签主要是在复杂的嵌套控制流语句区分要终止哪个循环或者哪个switch语句。
  • 呵呵内容太多了,翻译不清楚地请见谅,还有地方不明白的可以留言,或者qq我:712641411。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值