03-Swift控制流

一、for循环


  • for-in循环,遍历集合里面的每个元素:
// 遍历的元素是1到3的数字
for index in 1...3 {  // index是每次循环开始时自动赋值,而且也不用声明
    print(index);
}
输出结果: 1  2  3

当不需要区间序列内的值,可以用_来忽略对值的访问:

int sum = 0;
for _ in 1...3 {  
    sum += 1;
    print(sum);
}
输出结果: 3

遍历一个数组的所有元素:

let names = ["张三","李四","王五"];
for name in names {
    print(name);
}
输出结果:
  张三
  李四
  王五

遍历一个字典来访问它的键值对。遍历时,字典每项元素会以(key,value)元组形式返回:

let dict = ["name":"swift", "age":"2", "version":"3.0"];
for (key,value) in dict {
    print("\\\\(key):\\\\(value)");
}
输出结果:
version:3.0
age:2
name:swift
(备注:字典遍历顺序和插入顺序不同,是因为字典内部是无序的)
  • for循环,使用条件判断和递增方法,标准C样式for循环:
// 这之后index++将会被swift移除,所以循环更多选择for-in
for var index=0; index<3; index++ {
    print("index:\\\\(index)");
}
输出结果:
index:0
index:1
index:2

<br />

二、while循环


  • while循环,每次在循环开始时,进行条件判断是否符合:
var index = 3;
while index > 0 {    // 先判断再执行
    index -= 1;
    print(index);
}
输出结果: 2   1   0
  • repeat-while循环,每次在循环结束时,进行条件判断是否符合:
    ``` swift`
    var index = 3;
    repeat {
    index -= 1;
    print(index);
    } while index > 0; // 先执行,再进行判断
    输出结果: 2 1 0


<br />
#三、条件语句
---
 swift提供了两种条件语句:`if`和`switch`。一般,但条件较为简单且可能的情况较少时,使用`if`语句。而`switch`更适合用于条件较复杂、可能情况较多、需要用到匹配`(pattern-matching)`的情况。
- `if`语句,当且仅当条件为`true`时,才执行相关代码:
```swfit`
let age = 23;
if age >= 18 {  // 符合条件
    print("已成年...");
} else {      // 否则,即不符合条件
    print("未成年的小屁孩...");
}
输出结果:  已成年...
  • switch语句会尝试把某个值与若干个模式(pattern)进行匹配,匹配成功则执行对应的代码:
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
    print("\\\\(someCharacter)是元音”);
case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
     "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
    print("\\\\(someCharacter)是辅音”);
default:    // 默认分支,处理其他情况的
    print("\\\\(someCharacter)即不是元音也不是辅音”);
}
输出结果: "e是元音”

(注:在swift中,case分支最后break不是必须的。当匹配的case分支中代码执行完毕后,程序会终止switch语句,即不会继续执行下一个case分支。)

  • switch的区间模式。case分支的模式可以是一个值区间:
    ``` swfit`
    let num = 999;
    switch num {
    case 0...9:
    print("一位数");
    case 10..<100:
    print("两位数");
    case 100..<1000:
    print("三位数");
    case 1000...9999:
    print("四位数");
    default :
    print("其他");
    }
    // 输出结果: 三位数

- `switch`的元组模式。`case`分支的模式可以是元组,元组中的元素可以是值,也可以是区间,另外,使用下划线`_`可以匹配所有可能的值:
``` swfit`
// 以0,0为中心点,4*4的矩形,确定点的位置
let point = (0,1);
switch point {
case (0, 0):
    print("坐标原点");
case (_, 0):    // _ 匹配所有可能值
    print("在x轴上");
case (0, _):
    print("在y轴上");
case (-2...2, -2...2):
    print("在矩形内");
default:
    print("在矩形外");
}
// 输出结果:  在y轴上
点是否在矩形内
  • switch的值绑定Value Bindings模式。case分支的模式允许将匹配的值绑定到一个临时的常量或变量,而这常量或变量在该case分支中就可以被引用---这种行为就成为值绑定(Value Bindings)
// 判断点是否在x/y轴中
let point = (3,3);
switch point {
case (let x, 0):
    print("在x轴上: \\\\(x)");  // 绑定后,在这里即可以进行使用
case (0, let y):
    print("在y轴上: \\\\(y)");
case let(x, y):
    print("具体坐标: (\\\\(x),\\\\(y))");
}
输出结果:  具体坐标:3,3
点是否在x/y轴中
  • switchwhere模式。case分支的模式可以使用where来判断额外条件:
// 判断点是否在坐标系的对角线上
let point = (-3,3);
switch point {
case let(x, y) where x == y:
    print("在x==y对角线上");
case let(x,y) where x == -y:
    print("在x==-y对角线上");
case let(x, y):
    print("具体坐标: (\\\\(x),\\\\(y))");
}
输出结果:  在x==-y对角线上
点是否在坐标系的对角线上

<br />

四、控制转移语句


控制转移语句,是改变代码的执行顺序,通过它可以实现代码的跳转。

  • continue即循环体立即停止本次循环,重新开始下一次循环,但并不是离开整个循环体:
for index in 1...5 {
    if index == 3 {    // index为3的时候,停止本次循环,重新下一次循环
        continue;
    }
    
    print(index);
}
输出结果: 1   2   4    5
  • break语句会立即结束循环体:
for index in 1...5 {
    if index == 3 {  // index为3的时候,即退出for-in
        break;
    }

    print(index);
}
输出结果: 1   2
  • fallthrough贯穿语句。在swift中switch不会从上一个case分支执行到下一个case分支中。而在C语言中,在每个case分支之后,需要加上break语句来阻止自动执行到下一个case分支中。如果你需要C语言中的贯穿特性,每个需要该特性的case分支中加入fallthrough关键字:
let index = 3;
switch index {
case 1:
    print("早上好");
case 2:
    print("中午好");
case 3:
    print("下午好");
    fallthrough;    // 表需要贯穿特性
case 4:
    print("晚上好");
    fallthrough;    // 表需要贯穿特性
default:
    print("洗洗睡");
}
输出结果: 
下午好
晚上好
洗洗睡

注意:fallthrough关键字不会检查它下一个将会执行case中的匹配条件。fallthrough简单地使代码执行继续连接到下一个case中的执行代码,这就和C语言的switch语句特性一样的。

  • 带标签的语句。switch代码中是可以嵌套循环体和switch来创建复杂的控制流结构。但循环体和switch代码块两者都可以使用break语句来提前结束整个方法体。因此要明确指定break语句想要终止的是哪个循环体或哪个switch代码块。关键字continue也一样可以指定。
// while循环,并指定这个标签为loop1
loop1:while index < 3 {
    index += 1;
    
    loop2:for temp in 1...3 {
        // 当index为2时候结束loop2循环
        if index == 2 {
            print("下一次再见,swift\\\\(index)-\\\\(temp)");
            break loop2;
        }
        
        // 当index为3的时候,最外层loop1循环将结束
        if index == 3 {
            print("不再见...");
            break loop1;
        }
        
        print("swift\\\\(index)-\\\\(temp)前来报到...");
    }
}
输出结果:
swift1-1前来报到...
swift1-2前来报到...
swift1-3前来报到...
下一次再见,swift2-1
不再见...

(备注: return函数的返回值,throw错误/异常的抛出)

<br />

五、退出操作


  • guard语句类似于if语句,执行取决于与表达式的布尔值(在自定义异常的时候使用到)。可以使用guard语句来要求条件必须是真时,以执行guard语句后的代码。不同于if语句,一个guard语句总是有一个else分句,如果天剑不为真则执行else分句中的代码:
func greet(person: [String: String]) {
    // 判断关键字name对应是否有值
    guard let name = person["name"] else {
        return; // 如果没有值,那么就直接退出
    }
    print("Hello \\\\(name)");

    // 关键字location对应是否有值
    guard let location = person["location"] else {
        print("你在哪里?")
        return
    }
    print("我正在购买到\\\\(location)的机票")
}
greet(["name": "Swift"]);
输出结果: Hello Swift    你在哪里?
greet(["name": "Swift", "location": "美国"]);
输出结果: Hello Swift    我正在购买到美国的机票

<br />

六、检测API可用性


  • swift有检查API可用性的内置支持,这可以确保我们不会不小心地使用对于当前部署目标不可用的API,从而导致程序在编译期间报错:
/** 
参数1:在iOS系统上,只有iOS 9及更高版本中执行;
参数2:在OS X系统上,只有 OS X  v10.10及更高版本中执行;
参数3:' * '必须写的,用于处理未来潜在的平台;
*/
if #available(iOS 9, OSX 10.10, *) {
    // 在 iOS 使用 iOS 9 的 API, 在 OS X 使用 OS X v10.10 的 API
} else {
    // 使用先前版本的 iOS 和 OS X 的 API
}


注:xcode7.3环境

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容