swift_014(Swift 的控制流)


//***********swift学习之14--控制流--***************************

// 1.控制流有哪些?

/*

 Swift提供了所有C语言中相似的控制流结构。包括forwhile循环;ifswitch条件语句;breakcontinue跳转语句等。 Swift还加入了for-in循环语句,让编程人员可以在遍历数组,字典,范围,字符串或者其它序列时更加便捷。

 相对于C语言,Swiftswitch语句的case语句后,不会自动跳转到下一个语句,这样就避免了C语言中因为忘记break而造成的错误。另外case语句可以匹配多种类型,包括数据范围,元组,或者特定的类型等。switch语句中已匹配的数值也可以被用在后续的case语句体中,where关键词还能被加入任意的case语句中,来增加匹配的方式。

*/


// 1.1 for循环的一般结构


// swift 3.0 推荐这种

var index1: Int = 0

for index1 in 0 ..< 3 {   // ..两个点

    print("index is \(index1)") // index 不会

}

print("The loop statements were executed \(index1) times")

// 在上面的例子中,index在每一次循环开始前都已经被赋值,因此不需要在每次使用前对它进行定义。每次它都隐式地被定义,就像是使用了let关键词一样。注意index是一个常量。

// 注意:index只在循环中存在,在循环完成之后如果需要继续使用,需要重新定义才可以。



// 1.2 for in循环


// 如果你不需要序列中的每一个值,可以使用_来忽略它,仅仅只是使用循环体本身:

let base = 3

let power = 10

var answer = 1

for _ in 1...power { // 三个点

    answer *= base

}

// 310 次方

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



// 1.3 for in循环遍历数组的元素

let forRoopArray = ["zhanSan","liSi","xiaoMing","xiaoFang"]

for name in forRoopArray {

    print("hello \(name)!")

}


// 1.4 for in循环遍历字典的元素

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

for (animalName,legCount) in numOfLegs {

    print("\(animalName) \(legCount)条腿")

}


// 1.5 我们也可以使用enumerate()方法来进行字典遍历,返回的是字典的索引及 (key, value) 对,实例如下:

var someDict:[Int:String] = [1:"One", 2:"Two", 3:"Three"]

for (key, value) in someDict.enumerated() {

    print("字典中index \(key) 对应的键值对 \(value)")

}


// 2 while循环

// while循环执行一系列代码块,直到某个条件为false为止。这种循环最长用于循环的次数不确定的情况。Swift提供了两种while循环方式:

// (1)while循环,在每次循环开始前测试循环条件是否成立

// (2)repeat-while循环,在每次循环之后测试循环条件是否成立


// 2.1 while循环

// while循环由一个条件语句开始,如果条件语句为true,一直执行,直到条件语句变为false

let finalSquare = 25

var board = Array (repeating: 0 , count: finalSquare + 1 )

var board1 = [Int] (repeating: 0, count: finalSquare + 1)

var board2 = [Float] (repeating: 0.5, 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

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("\(square) == \(finalSquare) Game over!")



// 2.2 repeat-while循环

// 另一种while循环是repeat-while循环。在这种循环中,循环体中的语句会先被执行一次,然后才开始检测循环条件是否满足,下面是repeat-while循环的一般形式


let doFinalSquare = 25

var doBoard = [Int](repeating: 0, count: doFinalSquare + 1)

doBoard[03] = +08; doBoard[06] = +11; doBoard[09] = +09; doBoard[10] = +02

doBoard[14] = -10; doBoard[19] = -11; doBoard[22] = -02; doBoard[24] = -08

var doSquare = 0

var doDiceRoll = 0



repeat {

    // move up or down for a snake or ladder

    doSquare += doBoard[doSquare]

    // roll the dice

    doDiceRoll += 1

    if doDiceRoll == 7 { doDiceRoll = 1 }

    // move by the rolled amount

    doSquare += doDiceRoll

    

} while doSquare < doFinalSquare


print("\(doSquare) == \(doFinalSquare) Game over!")



// 3 条件语句

// 3.1 if 语句 很简单不再赘述



// 3.2 switch 语句

// switch中,每一个case分支都会被匹配和检测到,所有case没有提到的情况都必须使用default关键词。注意default关键词必须在所有case的最后。


// 下面的例子用switch语句来判断一个字符的类型:


let someCharacter: Character = "e"

switch someCharacter {

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

    print("\(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":

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

default:

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

}

// prints "e is a vowel"



// CObjective-C不同,Swift中的switch语句不会因为在case语句的结尾没有break就跳转到下一个case语句执行。switch语句只会执行匹配上的case里的语句,然后就会直接停止。这样可以让switch语句更加安全,因为很多时候编程人员都会忘记写break

// 每一个case中都需要有可以执行的语句,下面的例子就是不正确的:


let anotherCharacter: Character = "a"

switch anotherCharacter {

//case "a":

//case "A":

//    println("The letter A")

default:

    print("Not the letter A")

}



// C不同,switch语句不会同时匹配aA,它会直接报错。一个case中可以有多个条件,用逗号,分隔即可:

switch anotherCharacter {

    case "a","A":

        print(" the letter is A or a")

    default:

    print("Not the letter A or a")

}



// 3.3范围匹配

// switch语句的case中可以匹配一个数值范围,比如:

let count = 3_000_000_000_000

let countedThings = "stars in the Milky Way"

var naturalCount: String

switch count {

case 0:

    naturalCount = "no"

case 1...9:

    naturalCount = "several"

case 10...99:

    naturalCount = "tens of"

case 100...999:

    naturalCount = "hundreds of"

case 1000...999_999:

    naturalCount = "thousands of"

default:

    naturalCount = "millions and millions of"

}

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



// 3.4 元组 case中还可以直接测试元组是否符合相应的条件,_可以匹配任意值。

// 下面的例子是判断(x,y)是否在矩形中,元组类型是(Int,Int)


var imageView:NSImageView = NSImageView(frame: CGRect(x: 0, y: 0, width: 100, height: 100))

imageView.image = NSImage(named: "image_thumb.png")


let somePoint = (1, 1)

switch somePoint {

case (0, 0):

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

case (_, 0):

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

case (0, _):

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

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

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

default:

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

}



// 3.5 数值绑定

// case匹配的同时,可以将switch语句中的值绑定给一个特定的常量或者变量,以便在case的语句中使用。比如:


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

}



// 3.6 Where关键词

// switch语句可以使用where关键词来增加判断的条件,在下面的例子中:


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)) is just some arbitrary point")

}




// 4、控制跳转语句

// continuebreakfallthroughreturn

// 其中continuebreakfallthrough在下面详细介绍,return语句将在函数一章介绍。


// 4.1 continue语句告诉一个循环停止现在在执行的语句,开始下一次循环。

// 注意:在for-condition-increment循环中,increment增量语句依然执行,只是略过了一次循环体。


// 下面的例子实现的是去除一个字符串中的空格和元音字母,从而组成一个字谜:

let puzzleInput:String = "great minds think alike"

var puzzleOutput = ""

for character in puzzleInput.characters {

    switch character {

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

        continue

    default:

        puzzleOutput  += String(character)

    }

}

print(puzzleOutput)



// 4.2 break

// break语句将终止整个循环的执行,可以用在循环语句中,也可以用在switch语句中。

// swift 中的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

    print("The integer v")

default:

    break

}

if let integerValue = possibleIntegerValue {

    print("The integer value of \(numberSymbol) is \(integerValue).")

} else {

    print("An integer value could not be found for \(numberSymbol).")

}


// 4.3 fallthrough

// 由于Swift中的switch语句不会自动的因为没有break而跳转到下一个case,因此如果需要想C语言中那样,依次执行每个case的时候,就需要用到fallthrough关键词。


// 像下面这个例子一样,default分支最终都会被执行:


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

}

print(description)




// 4.5 标签语句


// switch和循环可以互相嵌套,循环之间也可以互相嵌套,因此在使用break或者continue的时候,需要知道到底是对哪个语句起作用。这就需要用到标签语句。标签语句的一般形式如下:

//label name: while condition {

//    statements

//}


// 下面的例子演示了如何使用标签语句以及嵌套的循环和switch

// 依然采用之前的那个梯子与蛇的游戏,第一步依然是设置初始值:


let finalSquare112 = 25

var board112 = [Int](repeating: 0, count: finalSquare112 + 1)

board112[03] = +08; board112[06] = +11; board112[09] = +09; board112[10] = +02

board112[14] = -10; board112[19] = -11; board112[22] = -02; board112[24] = -08


var square112 = 0

var diceRoll112 = 0

// 然后,使用一个while循环与switch的嵌套来完成游戏


gameLoop: while square112 != diceRoll112 {

    diceRoll112 += 1

    if diceRoll112 == 7 { diceRoll112 = 1 }

    switch square112 + diceRoll112 {

    case finalSquare112:

        // 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

        square112 += diceRoll112

        square112 += board112[square112]

    }

}

print("112 Game over!")

// 在这个代码中,将游戏的循环命名为gameLoop,然后在每一步移动格子时,判断当前是否到达了游戏终点,在break的时候,需要将整个游戏循环终止掉,而不是终止switch,因此用到了break gameLoop。同样的,在第二个分支中,continue gameLoop也指明了需要continue的是整个游戏,而不是switch语句本身。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值