// 控制流

// swift 提供了多种控制流结构,包括可以多次执行的 while 循环,基于特定条件选择执行不同分支的 if, guard 和 switch 语句,还有控制流程跳转到其它代码位置的 break 和 continue 语句

// swift 还提供了了 for-in 循环,用来更简单地遍历数组(array), 字典(dictionary), 区间(range), 字符串(String) 和其它序列类型

// swift 的switch 语句比C语言中更加强大, 在C语言中,如果某个 case 不小心漏写了 break, 这个 case 就会贯穿至下一个 case swift 无需写 case ,也无需写 break 所以不会发生贯穿的情况, case 还可以匹配很多不同的模式,包括间隔匹配, 元组(tuple) 和转换到特定类型. swift 语句的case 中匹配的值还可以绑定成临时变量或常量, 在 case 中使用, 也可以用 where 来描述更加复杂的匹配条件

// for-In 循环

// 你可以使用 for-in 循环来遍历一个集合中的所有元素, 例如数字范围,数组中的元素或者字符串中的字符

for index in 1...5 {

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

}

// 上面的例子中, index 是一个每次循环遍历开始时被自动复制的常量. 这种情况下, index 在使用前不需要声明, 字需要将它包含在循环的声明中,就可以对其进行隐式声明,而无需 使用 let 关键字声明

// 如果你不需要区间序列内每一项的值, 你可以使用 (_) 替代变量名来忽略这个值

// (_)(替代循环的变量) 能够忽略当前值, 并且不提供循环遍历时对值的访问

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

for name in names {

print("Hello, \(names)")

}

// 你也可以通过遍历一个字典来访问它的键值对,遍历字典时候.字典的每项元素会以 (key, value) 元组的形式返回, 你可以在 for-in 循环中使用显式的常量名称来解读 (key, value) 元组

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

for (animalName, legCount) in numberOfLegs {

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

}

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

// While

// While 循环从计算一个条件开始, 如果条件为 true ,会重复运行一段语句, 直到条件变为 false, 才会结束跳过

// Repeat-While

// While 循环的另一种形式, 它和 while 的区别是在判断循环条件之前 ,先执行一次循环的代码块, 然后重复循环知道条件 false

// Swift 语言的 repeat-while 循环和其它语言的 do-while 循环是类似的

//repeat{

//

//}while condtion

// 条件语句

// 根据特定条件执行特定的代码通常是十分有用的,当错误发生时, 你可能想运行额外的代码, 或者,当值太大或者太小的时候,向用户显示一条消息, 要实现这些功能, 你就需要使用条件语句

// swift 提供两种类型的条件语句, if 语句 和 switch 语句, 通常,当条件较为简单而且可能 的情况横少时 , 使用 if 语句, 而 switch 语句更适用于条件比较复杂的,有更多排列组合的时候, 并且在 switch 在需要用到模式匹配的情况下回更有用

// If

// if 语句最简单的形式就是 只包含一个条件 ,当改条件为 true 的时候, 才会执行相关代码

var temperatureInFahrenHeit = 30

if temperatureInFahrenHeit <= 32 {

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

}

// 当然, if 语句允许二选一执行, 叫做 else 从句, 也就是当条件为 FALSE 时 ,执行 else 语句

// Switch

// Switch 语句会尝试把某个值与若干个模式进行 匹配, 根据第一个匹配成功的模式, switch 语句会执行对应的代码,当有可能的情况较多时, 通常用 switch 语句替换 If 语句

// switch 语句最简单的形式就是把某个值与一个或若干个相同类型的值做比较

switch 1 {

case 1:

print(1)

default:

print("no value")

}

// switch 语句由多个 case 构成,每个有 case 关键字开始,为了匹配某些特定的值, swift 提供了几种 方法来进行更复杂的模式匹配,

// 与 if 语句类似, 每一个 case 嗾使代码执行的一条分支, switch 语句会决定哪一条分支应该被执行, 这个流程被称作更具给定的值切换

// switch 语句必须是完备的,这就是说,每一个可能的值都必须至少有一个 case 分支预支对应, 在某些不可能涵盖所有值的情况下, 你可以使用默认 (default) 分支来涵盖其他所有没有对应值的情况, 这个默认分支必须在 switch 语句的最后面

// 例如

let someCharacter: Character = "z"

switch someCharacter {

case "a":

print("The first letter of the alphbet")

case "z":

print("The last letter of the alphabet")

default:

print("Some other character")

}

// 不存在隐式的贯穿

// 与 C 和 OC 中的 switch 语句不同,在 swift 中,当匹配 case 分支的代码执行完毕后, 程序会终止 switch 语句,而不会继续执行下一个 case 分支, 这就是说, 不需要再 case 分支中显式地使用 break 语句, 这使得 switch 语句更加安全, 更易用, 也避免了 break 漏写而产生的错误

// 注意 : 虽然在swift 中 break 不是必须的, 但你依然可以在 case 分支中的代码执行完毕之前使用 break 跳出

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

//let anotherCharacter: Character = "a"

//switch anotherCharacter {

//case "a": // 无效,这个分支下面没有语句

//case "A":

//    print("The letter A")

//default:

//    print("Not the letter A")

//}

//// 这段代码会报编译错误

// 不像 C语言里的 switch 语句,在swift 中, switch 语句 不会一起匹配 "a" 和 "A", 相反的,上面的代码会引起编辑器错误, case "a": 不包含任何可执行语句, 这就避免了意外地从一个case 分支贯穿到另外一个, 使得代码更加安全, 也更直观

// 为了让单个 case 同时匹配 a 和 A ,可以将这两个值合成一个复合匹配,并且用逗号隔开:

let anotherCharacter: Character = "a"

switch anotherCharacter {

case "a", "A":

print("The letter A")

default:

print("Not the letter A")

}

// 输出 "The letter 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 语句中测试多个值, 元组中的元素可以是值, 也可以是区间, 另外,使用下划线(_) 来匹配所有可能的值

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"

// 值绑定 (Value Bindings)

// case 分支允许将匹配的值绑定到一个临时的常量或变量, 并且在 case 分支体内使用 -- 这种行为称为值绑定, 因为匹配的值在 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))")

}

// 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 后面, 并且用逗号隔开, 当 case 后面的任意一种模式匹配的时候, 这条分支就会被匹配,并且,如果匹配列表过长,还可以分行书写

let somesCharacter: 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"

// 复合匹配同样可以包含绑定值, 复合匹配里面所有的匹配模式, 都必须包含相同的的值绑定,并且没一个绑定都必须获取到相同类型的值,这保证了, 无论复合匹配中的那个模式发生了匹配,分支体内的代码,都能获取到绑定的值,并且绑定的值都有一样的类型

// 控制转移语句

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

// continne

// break

// fallthrough

// return

// throw

// continue

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

// break

// break 语句会立即结束整个控制流的执行, 当你想要更早的结束一个switch 代码块或者一个循环体的时候, 你可以使用 break

// 循环语句中的 break

// 当在一个循环体中使用 break 的时候, 会立即中断改循环体的执行, 然后跳到表示循环体结束的大括号 (}) 后的第一行代码, 不会再有本次循环的代码被执行, 也不会再有下次的循环发生

// Switch 中的 break

// 当在一个 switch 中使用 break 的时候, 会立即中断改 switch 代码块的执行, 并且跳到表示 switch 代码块结束的大括号 (}) 后的第一行代码

// 这种特性可以被用来匹配或者忽略一个或者多个分支, 因为 swift 的 switch 需要包含所有的分支并且不允许有空的分支存在, 有事为了你的意图更加明显, 需要特意匹配或者忽略某个分支, 那么当你想忽略某个分支时, 可以在改分支内写上 break 语句, 当那个分支被匹配到时, 分支内的 break 语句立即结束  switch  代码块

// 注意 : 当一个 switch 分支紧紧包含注释时, 会被编辑时错误, 注释不是代码语句而且也不能让 switch 分支达到被忽略的效果, 应该使用 break来忽略某个分支

// 贯穿

// swift 中的 switch 不会从上一个 case 分支落入到下一个 case 分支中, 相反,只要第一个匹配到的 case 分支完成了它需要执行的语句,整个 switch 代码块完成了它的执行, 相比之下, C语言要求你显式地插入 break 语句到每个 case 的结尾来阻止自动落入到 下一个 case 分支中, swift 的这种避免落入下一个分支的特性一位整个他的 switch 功能要比 C语言 的更加的清晰和可预测, 可以避免无意识执行多个 case 分支从而引发的错误

// 如果你确实需要 C语言的贯穿的特性, 你可以在每个需要改特性的 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)

// 注意 : fallthrough 关键字不会检查下一个将会落入执行的 case 分支的匹配条件, fallthrough 鸡蛋地使得代码继续连接到下一个 case 中的代码, 这个和 C语言标准 switch 语句特性是一样的

// 带标签的语句

// 在 swift 中. 你可以在循环体和条件语句中嵌套循环体和添加语句来创造复杂的控制流结构, 并且,循环体和条件语句都可以使用 break 语句来提前结束整个代码块

// 为了实现这个目的, 你可以使用标签 (statement label) 来标记一个循环体或者条件语句, 对于一个条件语句, 你可以使用 break 加标签的方式,来结束这个被标记的语句, 对于一个循环语句,你可以使用 break 或者 continue 加标签吗来结束或者继续这条被标记语句的执行

// 声明一个带标签的语句是通过在该语句的关键字的同一行前面放置一个标签, 作为这个语句的前导关键字 ,并且该标签后面跟随一个冒号, 下面的是一个 while 循环体的标签语法,同样的规则适用于所有的循环体和条件语句

// 提前退出

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

// 如果 guard 语句的条件被满足, 则执行 guard 语句大括号后面的代码, 将变量或者常量的可选绑定 guard 语句的条件 ,都可以保护 guard 语句后面的代码

// 如果条件不被满足, 在 else 分支 上的代码就会被执行,这个分支必须转移控制以退出 guard 语句出现的代码段, 它可以用控制转移语句如 : return ,break, continue,或者 throw , 或者调用一个不返回的方法或函数

// 相比于可以实现同样功能的 if 语句, 按需使用 guard 语句会提升我们代码的可读性,它可以使你的代码连贯的被执行而不需要将它包在 else 块中, 它可以使你在紧邻条件判断的地方,吗处理违规的情况

// 检测 API 的可用性

// swift 内置支持检查 API 可用性, 这可以确保我们不会再当前部署的机器上, 不小心使用了不可用的 API

// 编辑器使用 SDK 中的可用信息来验证我们代码中的使用的所有的 API 在项目指定的部署目标上是否可用, 如果我们尝试使用一个不可用的 API, swift 会在编辑是报错

// 我们在 if 或 guard 语句中使用 可用性条件 (availability condition) 去有条件的执行一段代码, 来运行时判断调用的 API 是否可用, 编辑器使用从可用性条件语句中获取的信息去验证,在这个代码块中是可用

if #available(iOS 10, macOS 10.12, *) {

}else{

}

// 以上可用性条件指定, 在 iOS 中, if 语句的代码块仅仅在 iOS 10 以及更高的系统下运行; 在 MacOS 中, 仅在 macOS 10.12 以及更高的版本才会运行, 最后一个参数 (*) 是必须的, 用于指定在所有其它平台中, 如果版本高于你的设备指定的最低版本, if 语句的代码块也会执行

// 在它一般的形式中, 可用性条件使用了一个平台名字和版本的列表, 平台名字可以是 iOS, macOS, watchOS 和 tvOS , 除了指定像 iOS 8 这样的主版本号, 我们可以指定 iOS 8.3 以及 macOS 10.10.3 的子版本号

Swift 学习- 06 -- 控制流的更多相关文章

  1. swift学习:第一个swift程序

    原文:swift学习:第一个swift程序 最近swift有点火,赶紧跟上学习.于是,个人第一个swift程序诞生了... 新建项目

  2. Swift学习目录

    本学习基于苹果官方Swift学习材料,保留了原版90%左右的内容(一些项目开发中基本不用的知识点没有整理),并根据理解进行整理.如对原版感兴趣,可以直接单击链接阅读和学习. 第一部分 基础篇 1.基本 ...

  3. Swift 学习网址精选 By HL

    虽然目前iOS大部分的项目开发语言用的不是Swift,但随着Swift的不断强大,取代Objective-C 指日可待,所以学习Swift是十分必要的.但毕竟是亲儿子,目前只有Foundation被翻 ...

  4. 【swift学习笔记】二.页面转跳数据回传

    上一篇我们介绍了页面转跳:[swift学习笔记]一.页面转跳的条件判断和传值 这一篇说一下如何把数据回传回父页面,如下图所示,这个例子很简单,只是把传过去的数据加上了"回传"两个字 ...

  5. 今天开始Swift学习

    今天开始Swift学习  在此记录笔记  以备之后查阅! allenhuang

  6. iOS ---Swift学习与复习

    swift中文网 http://www.swiftv.cn http://swifter.tips/ http://objccn.io/ http://www.swiftmi.com/code4swi ...

  7. JavaScript学习06 JS事件对象

    JavaScript学习06 JS事件对象 事件对象:当事件发生时,浏览器自动建立该对象,并包含该事件的类型.鼠标坐标等. 事件对象的属性:格式:event.属性. 一些说明: event代表事件的状 ...

  8. Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论

    Java虚拟机JVM学习06 自定义类加载器 父委托机制和命名空间的再讨论 创建用户自定义的类加载器 要创建用户自定义的类加载器,只需要扩展java.lang.ClassLoader类,然后覆盖它的f ...

  9. 12套swift学习资源分享

    虽然objective-c编程语言在过去很长一段时间都是iOS应用开发的基础语言,且很多iOS开发者对其也深爱有佳,但是随着swift编程语言的问世,迅速发展为开发者追捧的语言.且今年伴随着swift ...

随机推荐

  1. TensorFlow从入门到理解(五):你的第一个循环神经网络RNN(回归例子)

    运行代码: import tensorflow as tf import numpy as np import matplotlib.pyplot as plt BATCH_START = 0 TIM ...

  2. Spark思维导图之Spark SQL

  3. eclipse快捷键调试总结 -转--快捷键大全

    (1)Ctrl+M --切换窗口的大小(2)Ctrl+Q --跳到最后一次的编辑处(3)F2      ---重命名类名 工程名 --当鼠标放在一个标记处出现Tooltip时候按F2则把鼠标移开时To ...

  4. shell编程 之 流程控制(条件语句和循环语句)

    1 if ...else... 基本格式: if condition then commend else commend fi 当然也可以写到一行,用[ ]表明边界,用:表示分行.比如: if [ $ ...

  5. python初级实战-----主机在线情况监控web

    背景 公司有600多台服务器,打算写一个小程序,能一眼看见哪些服务器不在线. 大体思路是: 1.把所有服务器ip存进数据库,ping命令判断服务器是否在线 2.更新数据库中ip的状态 3.简单的web ...

  6. OGG选择捕捉和应用模式

    本章包含的信息可帮助您确定适用于数据库环境的捕获和应用模式. 主题: Oracle GoldenGate捕获和应用进程概述 决定使用哪种捕捉方法 决定使用哪种应用方法 同时使用不同的捕捉和应用模式 切 ...

  7. CF1108F MST Unification

    题目地址:CF1108F MST Unification 最小生成树kruskal算法的应用 只需要在算法上改一点点 当扫描到权值为 \(val\) 的边时,我们将所有权值为 \(val\) 的边分为 ...

  8. 【sql inject】sql盲注技巧

    SAMPLE 知识点 使用 AND 1 = 1 / 1 或者 1 = 1 / 0 判断是否存在注入,如果正确就会返回页面,如果错误就是1/0语法错误使得页面报错: queueID = 743994 A ...

  9. wxpy: 用 Python 玩微信【转】

    转自:https://wxpy.readthedocs.io/zh/latest/index.html 微信机器人 / 可能是最优雅的微信个人号 API wxpy 在 itchat 的基础上,通过大量 ...

  10. canner CMS 系统 (公司在台湾) https://www.canner.io/

    canner  CMS 系统 (公司在台湾) https://www.canner.io/ https://github.com/Canner/canner 一种创新的CMS构建方式,采用 Nodej ...