Swift 流程控制(四)

for-in 循环

  • 使用 for-in 循环来遍历序列,比如一个返回的数字,数组中的元素或者字符串的字符。
for i in 0...3 {
    print(i)
}
for c in "Hello,World" {
    print(c)
}
let names = ["zhangsan","lisi","wangwu","zhaoliu"]
for name in names {
    print(name)
}
  • 如果你不需要序列的每一个值,你可以使用下划线来取代遍历名以忽略值。
let base = 3
let power = 5
var answer = 1
for _ in 1...power {
    answer *= base
}
print("\(base) to the power of \(power) is \(answer)")
输出
3 to the power of 5 is 243

for-in 遍历字典

  • 当字典遍历时,每一个元素都返回一个(key,value)元祖,你可以字 for-in 循环体中使用显式命名常亮来分解(key,value)元祖成员。
let numberOfLegs = ["spider":8,"ant":6,"cat":4]

for (animalName,legCount) in numberOfLegs {
    print("\(animalName) has \(legCount)")
}

for t in numberOfLegs {
    print("\(t.0) has \(t.1) legs")
}
输出
ant has 6
cat has 4
spider has 8
ant has 6 legs
cat has 4 legs
spider has 8 legs

for-in 分段区间

  • 使用 stride(form: to: by: )函数来跳过不想要的标记(开区间)
  • 闭区间也同样适用,适用 stride(from: through: by) 即可。
let minuteInterval = 10
////开区间
for tickMark in stride(from: 0, to: 50, by: minuteInterval) {
    print(tickMark)
}
输出
0
10
20
30
40
////闭区间
for tickMark2 in stride(from: 0, through: 50, by: minuteInterval){
    print(tickMark2)
}
输出
0
10
20
30
40
50

while 循环

  • repeat-while 循环 (Objective-C do-while)
var count = 0
repeat {
    print(count)
    count += 1
} while count < 5

switch

  • switch 语句会将一个值与多个可能的模式匹配。然后基于第一个成功匹配的模式来执行合适的代码块。
  • switch 语句一定得是全面的。就是说给定类型里面一个值都得被考虑到并且匹配到一个switch 的 case。如果无法提供一个 switch case 所有可能的值,你可以定义一个默认匹配所有的 case 来匹配所有未明确出来的值。这个匹配所有的情况用关键字 default 标记,并且必须在所有 case 的最后出现。
  • Objective-C switch 语句如果不全面,仍然可以运行
char c = "z"
switch (c) {
    case "a":
        print("The first letter of alphabet");
        break;
    case "z":
        print("The last letter of alphabet");
        break;
}

而 swift 报错,必须添加默认的defaule

let someCharacter: Character = "z"
switch someCharacter {
case "a":
    print("The first letter of alphabet")
case "z":
    print("The last letter of alphabet")
}
  • 相比 C 和 Objective-C 里 switch 语句来说,Swift 里的 switch 语句不会默认从匹配 case 的末尾贯穿到下一个 case 里。
  • 相反,整个 switch 语句会在匹配到第一个 switch 的 case 执行完毕之后退出,不再需要显示的 break 语句。
没有隐式贯穿
  • 每一个 case 的函数体必须包含至少一个可执行的语句。
  • 在一个 switch 的 case 中 匹配多个值可以用逗号分隔,并且可以写成多行。
let anotherCharacter:Character = "a"
switch anotherCharacter {
case "a","A":
    print("The letter A")
default:
    print("Not the letter A")
}
输出
The letter A
区间匹配
  • swift 的 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 ara \(naturalCount) \(countedThings).")
输出
There ara dozens of moons orbiting Saturn.
元祖匹配
  • 你可以使用元祖来在一个 switch 语句中测试多个值
  • 使用下划线 (_) 来表明匹配所有可能的值
let somePoint = (1,1)
switch somePoint {
case (0,0):
    print("(0,0) is at the arigin")
case (_,0):
    print("(\(somePoint.0),0) is on the x-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
绑定值
  • switch 的 case 可以将匹配到的值临时绑定为一个常量或者变量,来给 case 的函数体使用。
  • 如果使用 var 关键字,临时的变量就会以合适的值来创建并初始化。对这个变量的任何改变都只会在 case 的函数体内有效。
let anotherPoint = (0,2)
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 an y value of \(y)")
case let(x,y):
    print("somewhere else at (\(x),\(y))")
default:
    print("没有匹配到")
}
where 字句
  • switch 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")
default:
    print("其他")
}
复合匹配
  • 多种情形共享同一个函数体的多个情况可以在 case 后写多个模式来复合,在每个模式之间用逗号隔开。如果任何一个模式匹配了,那么这个情况都会被认为是匹配的。如果模式太长,可以把它们写成多行。
let someCharacter:Character = "g"
switch someCharacter {
case "a","e","i","o","u":
    print("\(someCharacter) is a vowel")
case "b","c","d","f","g","h","j","k","l",
     "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")
}
复合匹配 - 值绑定
  • 复合匹配同样可以包含值绑定。所有复合匹配的模式都必须包含相同的值绑定集合,并且复合情况的每一个绑定都得有相同的类型格式。这才能确保无论复合匹配的那部分命中了,接下来的函数体重的代码都能访问到绑定的值并且值得类型也都相同。
let stillAnotherPoint = (9,0)
switch stillAnotherPoint {
case (let distance,0),(0,let distance):
    print("On an axis,\(distance) from the origin")
default:
    print("Not on an axis")
}

控制转移

  • continue
  • break
  • fallthroungh
  • return
  • throw
continue
  • continue 语句告诉循环停止正在做的事情并再次从头开始循环的下一个遍历。它是说"我不再继续当前的循环遍历了" 而不是离开整个的循环。
break
  • break 语句会立即结束整个控制流语句。当你想要提前结束 switch 或者循环语句或者其他情况时可以在 switch 语句或者循环语句中使用 break 语句。
  • 当在循环语句中使用时,break 会立即结束循环的执行,并且转移控制到循环结束花括号(})后的第一行代码上。当前遍历循环里的其他代码都不会被执行,并且余下的遍历循环也不会开始了。
  • 当在 switch 语句里使用时,break 导致switch 语句立即结束它的执行,并且转移控制到switch 语句结束花括号(})之后的第一行代码上。
fallthrough
  • 如果你确实需要 C 或者 Objective-C 风格的贯穿行为,你可以选择在 switch 每个 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.

语句标签

  • 可以用语句标签来给循环语句或者条件语句做标记。在一个条件语句中,你可以使用一个语句标签配合 break 语句来结束被标记的语句。在循环语句中,你可以使用语句标签来配合 break 或者 continue 语句来结束或者继续执行被标记的语句。

guard 和检查 API 可用性

guard
  • guard 语句,类似于 if 语句,基于布尔值表达式来执行语句。使用 guard 语句来要求一个条件必须是真才能执行 guard 之后的语句。与 if 语句不同,guard 语句总是一个 else 分句 —— else 分句里的代码会在条件不为真的时候执行。
func fooGuard(x: Int?) {
    guard let x = x where x > 0 else {
        // 变量不符合条件判断时,执行下面代码
        return
    }
    
    // 使用x
    x.description
}
  • guard 是对你所期望的条件做检查,而非不符合你期望的。又是和assert很相似。如果条件不符合,guard的else语句就运行,从而退出这个函数。
  • 如果通过了条件判断,可选类型的变量在guard语句被调用的范围内会被自动的拆包 - 这个例子中该范围是fooGuard函数内部。这是一个很重要,却有点奇怪的特性,但让guard语句十分实用。
  • 对你所不期望的情况早做检查,使得你写的函数更易读,更易维护。
检查API的可用性
  • Swift 拥有内置的对 API 可用性检查的功能,他能够确保你不会悲剧地使用了对部署目标不可用的API。
  • 你可以在 if 或者 guard 语句中使用一个可用性条件来有条件地执行代码,基于在运行时你想用的哪个 API 是可用的。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 221,548评论 6 515
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,497评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,990评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,618评论 1 296
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,618评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,246评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,819评论 3 421
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,725评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,268评论 1 320
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,356评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,488评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,181评论 5 350
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,862评论 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,331评论 0 24
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,445评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,897评论 3 376
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,500评论 2 359

推荐阅读更多精彩内容

  • 循环控制 for-in 循环 使用 for-in 循环来遍历序列,比如一个范围的数字,数组中的元素或者字符串中的字...
    迷心迷阅读 272评论 0 0
  • 1 if-else if 后面的条件可以省略小括号 条件后面的大括号不可以省略 2 while 3 For - 区...
    Aliv丶Zz阅读 409评论 0 0
  • 本文源自本人的学习记录整理与理解,其中参考阅读了部分优秀的博客和书籍,尽量以通俗简单的语句转述。引用到的地方如有遗...
    水中的蓝天阅读 492评论 0 0
  • 一. if if后面的条件可以省略小括号,条件后面的大括号不可以省略。 if后面的条件只能是Bool类型。 二. ...
    Imkata阅读 450评论 0 0
  • 渐变的面目拼图要我怎么拼? 我是疲乏了还是投降了? 不是不允许自己坠落, 我没有滴水不进的保护膜。 就是害怕变得面...
    闷热当乘凉阅读 4,249评论 0 13