Swift 控制流(笔记)

/***************************** 控制流 Control Flow ***************************/


/**

*  For 循环

*  While 循环

条件语句

控制转换语句 (Control Transfer Statements)

提前退出

检测 API 的可用性

*/



// 类似C语言的流程控制结构,包括可以多次执行的任务Forwhile循环.基于特定的选择执行不同的分支if , guard switch语句,还有控制流跳转到其他代码的breakcontinue


// Swift语句中,如果在case分支里无需写break,也不会发生贯穿到下一个case的现象

// case还可以匹配更多的类型模式,包括区间匹配,元祖和特定类型的表述


/**************************** For 循环**************************/


// for-in循环用于对一个集合里面的每一个元素进行遍历执行的一个语句

// for 循环,用来重复执行一系列语句直到达到特定条件,一般都是通过在每次循环完成后增加计数器的数量的值来判定


// for-in

for index in 1...5 {

    print("\(index) items 5 is \(index * 5)")

}

// 1 items 5 is 5

// 2 items 5 is 10

// 3 items 5 is 15

// 4 items 5 is 20

// 5 items 5 is 25

// 这个例子中,index是一个每次循环开始时都要自动赋值的常量,这种情况下,index在使用前不需要声明(隐士声明)



// * 如果你不需要知道区间序列内每一项的值,那么你可以使用下划线(_)替代变量名而忽略掉对值的访问

let base = 3

let power = 10

var answer = 1

for _ in 1...power {

    answer *= base

}

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

// 结果 3 to the power of 10 is 59049


// 使用循环遍历出一个数组的每一个元素

let names = ["Anna","Alex","Brian","Jack"]

for name in names {

    print("hello , \(name)")

}

// 结果 

/**

hello , Anna

hello , Alex

hello , Brian

hello , Jack

*/


// 遍历字典

// 字典的每一个元素已(key,value)元祖的形式返回

// 可以在for-in循环中使用显示的常量名称来解读[key,value]元祖

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

for (animalName,legCount) in numberOflegs {

    print("\(animalName)s have \(legCount)")

}

/**

ants have 6

cats have 4

spiders have 8

*/

// 字典元素的遍历顺序和插入顺序可能不同,字典的内容是无序的,所以遍历元素时不能保证顺序.


// For 循环

// 条件判定和递增方法,标准的C样式for循环

for var index = 0;index < 3;index++ {

    print("index is \(index)")

}

/**

index is 0

index is 1

index is 2

*/


// 标准格式

//for initialization;condition;increment {

//    statements;

//}


// 循环执行流程

/**

*  1,循环首次启动,初始化表达式(initalization expression)被调用一次,用来初始化循环所需的所有常量和变量

*  2,条件表达式(condition expression)被调用.如果表达式调用结果为false,循环结束,继续执行for循环关闭大括号(})之后的代码.如果表达式调用结果为true,则会自行大括号内部的方法

*  3,执行所有语句之后,执行递增表达式(increment expression).通常会增加或减少计数器的值,或者根据语句输出来修改某个初始化的变量.当递增表达式运行完成后,重复执行第2,条件表达式会再次执行

*/


// 在初始化表达式里面生成的常量或者变量是局部的量,如果想要在循环外使用,要再循环外先声明好再进行循环

var index:Int

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

    print("index is \(index)")

}

// index is 0

// index is 1 

// index is 2

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

// The loop statements were executed 3 times


// While 循环

// while 循环进行一系列的语句直到条件被判定为false.这类循环适合使用在第一代迭代前迭代次数未知的情况下.swift提供两种while循环形式:

/**

*  while 循环,每次在循环开始时计算条件是否符合

*  repeat-while 循环,每次在循环结束时计算条件是否符合

*/


// while循环从计算单一条件开始,如果条件是true,会重复执行一些列语句,直到条件变成false

// 一般情况下while循环格式

//while condition {

//    statements

//}


// 这个是书上的蛇与梯子的游戏,没法复制,看看吧

let finalSquare = 25

var board = [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


var square = 0

var diceRoll = 0

//while square < finalSquare {

//    // 模拟掷骰子

//    if ++diceRoll == 7 { // 每次自加1,当加到7的时候变为1

//        diceRoll = 1

//    }

//    print("diceRoll is \(diceRoll)")

//    // 根据点数移动

//    square += diceRoll

//    if square < board.count {

//        // 如果玩家还在棋盘上,顺着梯子爬上去或者顺子蛇滑下来

//        square += board[square]

//        print("square is \(square)")

//    }

//}

//print("Game over")


// wihle循环开始时,我们并不知道要进行多少次循环,如果满足条件就一直循环下去,只有在达到某个指标之后循环结束


// Repeat-While

// 他是判定循环条件之前,先进性一次循环,感觉就是Cdo-while


// 标准格式

/**

repeat {

   statements

}while condition

*/

repeat{

    print(square)

    // 顺着梯子爬上去或者是顺着蛇滑下来

    square += board[square]

    // 掷骰子

    if ++diceRoll == 7{

        diceRoll = 1

    }

    // 根据点数移动

    square += diceRoll

}while square < finalSquare

print("Game over")

// 跟上面比较,他是先执行一次再算,算好储备着给下次用

// 上面的方法是当时算,当时就用,所以要内部要判定一下square的值,防止数组越界


/**************** 条件语句 ********************/

// swift提供两种类型的条件语句:if语句和switch语句.

// 通常条件比较简单的话用if语句.而相对复杂的话用swich语句,swich可能情况较多且需要用到模式匹配


// if 语句就是简单的包含一个条件,而且在这个条件为true的时候执行语句

var temperatureInFahrenheit = 30

if temperatureInFahrenheit <= 32 {

    print("It's very cold ,Consider wearing a scarf")

}


// if 语句允许二选一,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")

}


// else 也是可以做判断的

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

}


// switch 语句会尝试把某个值与若干个模式进行匹配.

//switch some value to consider {

//    case value1:

//    respond to value1

//    case value2:

//    respond to value2

//    default:

//    otherwise, do something else

//}


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

}

// 输出 "e is a vowel”


// 不存在隐式贯穿

// swiftswitch不用写break,不存在隐式贯穿,但是也可以写,不会有影响


// 每一个case分支都必须至少包含一条语句,每个case分支里面不能为空

// swift语句不像C语言一样,他们不会同时匹配"a""A"


// 一个case可以包含多个模式,用逗号可以把他们分开


// 也可以贯穿,fallthrough语句


// 区间匹配

// case分支的模式也可以是一个值的区间.

let approximateCount = 62

let countedThings = "moons orbiting Saturn"

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

// 输出 There are dozens of moons orbiting Saturn.



// 元组

// 我们可以使用元组在同一个switch语句中测试多个值.

// 元祖中的元素可以是值,也可以是区间.另外,使用(_)来匹配所有可能的值.

// 下面的例子展示了如何用一个(Int,Int)类型的元祖来分来下图中的(x,y):


// 分配一个2 * 2 的正方形上面的点的代码

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

}

// 输出 "(1, 1) is inside the box”


// Swift允许多个case匹配同一个值 ,上面代码里(0,0)点可以匹配四个case

// 如果存在多个匹配,那么只会执行第一个被匹配到的case的分支



// 值绑定

// case分支的模式允许将匹配的值绑定到一个临时的常量或变量,这些常量或者变量在该分支case里可以被引用 -- 这种方法被称为值绑定

// 下面的例子展示了如何在一个(Int,Int)类型的元组中使用值绑定类分类下图中的点(x,y)

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

}

// 输出 on the x-axis with an x value of 2



/******************** Where **************************/

// case 分支模式可以使用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")

}

// 输出 (1,-1) is on the line x == y

// 这个没的说,自己领会吧

// case上创建一个元组(x,y),然后根据where判定,如果返回true.就会执行这个分支


/****************** 控制转移语句 ****************/

// 控制转移语句改变你代码的执行顺序,通过它你可以实现代码的跳转.swift有五种控制转移语句

/**

*  continue

*  break

*  fallthrough

*  return

*  throw

*/


// 这节讨论continue,breakfallthrough语句

// retrun语句在函数章节讲

// throw 语句会在错误抛出章节讨论


/****************** Continue *********************/

// continue 语句告诉一个循环体立刻停止本次循环迭代,重新开始下次循环迭代.

// 例如在说"本次循环迭代我已经执行完了",但是并不会离开整个循环体


// 注意: 在一个带有条件和递增的for循环体重,调用continue语句后,迭代增加仍会被计算求值.循环体继续像往常一样工作,仅仅只是循环体中的执行代码会被跳动.

// 下面的例子把一个小写字符串中的元音字符和空格字符移除,生成了一个含义模糊的短句:

let puzzleInput = "great minds think alike"

var puzzleOutput = ""

for character in puzzleInput.characters {

    switch character {

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

        continue

    default:

        puzzleOutput.append(character)

    }

}

print(puzzleOutput)

// 输出"grtmndsthnklk"


// 在上面的代码里,只要匹配到元音字母或者空格字符,就调用continue语句,使本次循环迭代结束,从新开始下次循环迭代.这种行为使switch匹配到元音字符和空格字符时不做处理,而不是让每一个匹配到字符都被打印


/******************* Break*******************/

// break 语句会立刻结束整个控制流的执行.

// 当你想要更早的结束一个switch代码块或者小个循环体时,直接使用break


// 循环语句中的break

// 当在一个循环体中使用break,会立刻中断该循环体的执行,然后跳转出表示循环体结束的大括号(})后的第一行代码.


// Swith语句中的break

// 当在一个switch代码块中使用break,会立刻中断该代码的执行,然后跳转switch代码块结束的大括号(})后的第一行代码.


let numberSymbol:Character = "" // 简体中文里的数字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 {

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

} else {

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

}

// 输出"The integer value of is 3."



/***************** 贯穿 Fallthrough ***********************/

// swift默认在每一个switch case语句里都写有break.不会出现贯穿的现象

// 如果你想要贯穿的效果发生,就在需要贯穿的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"

}

print(description)

// 结果是 The number 5 is a prime number,and also an integer



// 带标签的语句

// Swift,你可以循环体嵌套循环体来制造复杂的语句

// 你可以显示的创建break或者是continue语句来显示的指明结束的是哪个循环体


// 产生一个带标签的语句,是通过该语句的关键词的同一行前面放置一个标签,并且该标签还需要一个冒号

// 如下

//labelname:while condition {

//    statements

//}


let finalSquare1 = 25

var board1 = [Int](count: finalSquare1 + 1, repeatedValue: 0)

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

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

var square1 = 0

var diceRoll1 = 0


gameLoop:while square1 != finalSquare {

    if ++diceRoll == 7 {

        diceRoll = 1

    }

    switch square1 + diceRoll1 {

    case finalSquare:

        // 到达最后一个方块,游戏结束

        break gameLoop

    case let newSquare where newSquare > finalSquare1:

        // 超出最后一个方块.再掷一次骰子

        continue gameLoop

    default:

        // 本次移动有效

        square1 += diceRoll1

    }

}

print("Game over!")

// 这里给gameLoop生命了一下,

/**

如果骰子数刚好使玩家移动到最终的方格里,游戏结束。break gameLoop语句跳转控制去执行while循环体后的第一行代码,游戏结束。

如果骰子数将会使玩家的移动超出最后的方格,那么这种移动是不合法的,玩家需要重新掷骰子。continue gameLoop语句结束本次while循环的迭代,开始下一次循环迭代。

在剩余的所有情况中,骰子数产生的都是合法的移动。玩家向前移动骰子数个方格,然后游戏逻辑再处理玩家当前是否处于蛇头或者梯子的底部。本次循环迭代结束,控制跳转到while循环体的条件判断语句处,再决定是否能够继续执行下次循环迭代。

*/



// 提前退出

// if语句一样,guard的执行取决于一个表达式的布尔值.我们可以使用guard语句来要求条件必须为真时,以执行guard语句后的代码.不同于if代码,一个guard语句总是有一个else分句,如果条件不为真,则执行else分句

func greet(person:[String:String]){

    guard let name = person["name"] else {

        return

    }

    print("Hello \(name)")

    guard let location = person["location"] else {

        print("I hope the weather is nice near you.")

        return

    }

    print("I hope the weather is nice in \(location).")

}

greet(["name":"John"])

// prints "Hello John!"

// prints "I hope the weather is nice near you."

greet(["name": "Jane", "location": "Cupertino"])

// prints "Hello Jane!"

// prints "I hope the weather is nice in Cupertino.



// 检测API的可用性

// swift有检测API可用性的内部支持,这可以确保我们不会不小心地使用对于目前部署目标不可用的API.

// 如果不可用,直接报错

// 我们使用一个可用性条件在一个if 或者gurard语句中去有条件的执行一段代码

if #available(iOS 9,OSX 10.10,*){

    // iOS使用iOS9,OS X v10.10API

}else{

    // 使用先前版本的API

}


// if段的代码仅会在iOS9及更高版本的系统上执行,OSX仅在OS X v10.10版本及更高执行.最后一个参数*,是必须写的,用于处理未来潜在的平台


// 一般形式如下:可用性条件获取一些列平台名字和版本.平台名字可以是iOS,OSXwatchOS

// 除了特定的版本号如iOS 8,我们可以指定更小的版本如iOS 8.3

//if #available(platform name version,...,*) {

//    statements to execute if the APIs are available

//} else {

//    fallback statements to execute if the APIs are unavailable

//}  

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值