Swift5-外行零基础入门_9-控制流

2020-12-22  本文已影响0人  DavidShawn

控制流

什么是控制流?

所谓控制流,是用来控制一件事物的流程的。跟数据类型一样,同样是模拟我们大脑对现实生活的处理模式。
还记得我在开始举的例子的吗?一起来回顾一下:

早晨起(床),吃完(早餐),出门穿上(外套),花(两元钱)买了公交(车票),到公司开始(干活)。

我们的大脑能够轻松处理不同的数据类型,并且,我们实际上还在处理流程控制。让我们将上面这个例子细分一下:

  • 当我吃早饭时,只要没吃完,我就会一直吃,直到吃完或者吃饱;
  • 出门的时候检查有没有穿外套,穿了外套再出门;
  • 等公交车时,一辆接一辆,到了我要等的22路公交车,我就上车。
  • 如果我赶上了公交车,我就会到公司干活;

看吧,这里隐藏了相当多的条件或循环。只有通过这种流程控制,我们才能自由处理各个对象。我们的大脑相当强大,强大到你根本不需要费劲思考,这些事情就顺理成章的完成了。
再说回可怜的计算机,它需要你给他交待具体的任务安排。就像家长给上小学的孩子辅导作业一样,你需要把自己的认知也暂时拉低到小学水平,这样你才能给孩子讲明白题目。

有哪些控制流?

明白了什么是控制流,我们再来看看,Swift能接受哪些具体的命令来组织事务的控制流程:

1. for-in 循环

for-in循环有点像是做上楼梯(每个台阶踩一遍)点名(每个人都要点一遍)这种比较机械的工作。

var arrayNumbers = [1,2,3]
for i in arrayNumbers {
    print(i)
}
// 1,2,3
for i in 1...6 {
    print(i)
}
// 1,2,3,4,5,6

在这个例子中,i是1-6范围的值,每一步都取了一次当前值,并打印出来。
我们还可以仅仅执行这段循环,而不打印出i

for i in 1...6 {
    print("Hello")
}
// 打印了六遍"Hello"

在这个例子中,我们并没有在后面使用i,因此,我们可以用_代替i

for _ in 1...6 {
    print("Hello")
}
// 同样打印了六遍"Hello"
for i in stride(from:2, to: 100, by: 5) {
    print(i)
}
// 请自己在Playground中试一下结果。

这段代码实现了更加多的参数,在100这个范围内,从2开始数,每隔5数一次。

2. While 循环

while condition {
    statements
}

如果说for in做的工作比较机械的话,while,if,switch就比较有目的性了,我们先看while

var 饱腹感 = 1
while 饱腹感 < 8 {
    print("再吃一口……")
    饱腹感 += 1
}

分析这段代码:
首先,我很饿,用变量表示var 饱腹感 = 1,我给自己设定的条件是要吃到八成饱,饱腹感 < 8这实际上是一个判断,得出的就是一个判断值,也就是布尔值,是true or false
开始饱腹感是1,满足了饱腹感 < 8这个判断,就会执行while包起来的语句,我会再吃一口饱腹感就会加1。这时,代码运行完了,再从头运行,再次判断饱腹感的值,直到饱腹感=8的时候,条件就不满足了,就停止执行。
代码停止了,但是代码运行了7次再吃一口,也达到了目的。

repeat {
    statements
} while condition

理解了while的基本用法后,这里就很好理解。repeat-whilewhile的最大区别就是,无论什么条件,先执行一段代码。用我们的例子说明,就是管他饿不饿,先吃一口。上面的代码可以改为:

var 饱腹感 = 8
repeat {
    print("再吃一口……")
    饱腹感 += 1
}
while 饱腹感 < 8

这里,我把饱腹感的初始值设为8,虽然达到我的八成饱要求了,可是还要首先吃一口再说。

3. if 条件语句

if条件语句的意思是如果……就……,如果某个条件满足,就执行某个动作。一个萝卜一个坑,对预期控制的比较精确,也是编程语言中最常用的逻辑控制语句。

if condition {
    statements
}

condition同样是一个布尔值,statements是某个动作。
举个与生活相关的例子,如果天气晴朗,我就出门,用代码可以表示:

var 天气 = "晴朗"
if 天气 == "晴朗" {
    print("我要出门")
}

声明一下,为了便于理解,我们使用了中文名称作为变量,swift也能正常执行,但是在正式开发中,尽量避免这样使用。我能想到的最大缺点就是,这样做会影响兼容性,因为其他大部分人都不这么干。
上面这段代码,if的条件是成立的,因此会执行print()语句,如果你把天气的值改为其他,print()就不会执行了。

var 天气 = "下雨"
if 天气 == "晴朗" {
    print("我要出门")
} else {
    print("在家上网")
}

这里,加了else的意思是,除了天气 == "晴朗"这个条件,其他任何情况下,执行的动作。
满足一个条件,执行一个命令。如果不满足这个条件,就执行另一个命令。

var 天气 = "下雨"
if 天气 == "晴朗" {
    print("我要出门")
} else if 天气 == "下雨" {
    print("带伞出门")
} else {
    print("在家上网")
}

还有一种跟if条件很类似的 guard语句,主要在函数中使用,我们后面再说。

4. Switch 匹配语句

var 天气 = "晴朗"
switch 天气 {
case "晴朗":
    print("出门遛弯。")
case "下雨":
    print("出门带伞。")
default:
    print("在家上网。")
}

有没有发现switchif的最大区别?if后面的条件是布尔值,而switch后面是具体的数据,case后面的值也是从具体的数据中做选择。这样就灵活了很多。
但是要注意,case是顺序执行,一旦满足,后面就不再执行了。

var 天气 = "阴天"
switch 天气 {
case "晴朗", "阴天":
    print("出门遛弯。")
case "下雨":
    print("出门带伞。")
default:
    print("在家上网。")
}

我在第一行case中同时列举了两个条件,阴天也能出门遛弯。如果是用if,你需要这样列举天气=="晴朗" || 天气=="阴天",因为if后面只能跟布尔值。

var 分数 = 86
switch 分数 {
case 0...60:
    print("不及格")
case 61...80:
    print("良好")
case 81...100:
    print("优秀")
default:
    print("分数有误")
}
var 生命 = 90
var 魔法 = 86

switch (生命, 魔法) {
case (100, 100):
    print("英雄的状态完美!")
case (_, 30...100):
    print("可以释放魔法!")
case (0..<30, _):
    print("生命值低,危险!")
default:
    print("分数有误")
}

从这个例子,可以看到元组匹配的特性:能按元组精确匹配,使用_可以忽略某项匹配,可以按区间匹配。

var status = (30,60)
switch status {
case let (生命, 魔法):
    print("生命值:\(生命), 魔法值:\(魔法)")
    let 状态值 = 生命 + 魔法
    print("\(状态值)")
}

还可以配合where, 进行条件判断。会让绑定值显得更有意义。

var status = (30,60)
switch status {
case let (生命, 魔法) where 生命 + 魔法 > 100:
    print("可以释放魔法!")
case let (生命, 魔法):
    print("生命值:\(生命), 魔法值:\(魔法)")
    let 状态值 = 生命 + 魔法
    print("状态值(\(状态值))不够,不能释放魔法。")

}

调整状态值,能得到不同case执行动作,你可以在Playground中多试试。

7. 控制转移语句

最后,我们来简单介绍几条控制语句.
continuebreakfallthroughreturnthrow
return多用在函数中,throw多用在错误处理中,我们也放在后面介绍。
continuebreakfallthrough这几个语句主要用在前面所说的各种循环语句中,因为有时候这些循环的默认执行状态并不能满足需求,这时候,可以搭配这些语句,来控制流程的走向。
下面只是举了部分例子,先想象结果如何,然后在Playground中验证试试,也可以按自己的想法修改、调试:

var 天气 = ["晴朗","雷暴","阴天","下雨"]
for i in 天气 {
    if i == "雷暴" {
        continue
    } else {
        print("\(i)可以出门")
    }
}

在遍历循环的时候,如果遇到“雷暴”,用continue跳过,不做任何事情。

var 天气 = ["晴朗","阴天","下雨","雷暴","台风"]
for i in 天气 {
    if i == "雷暴" {
        break
    } else {
        print("\(i)可以出门")
    }
}

在遍历的过程中,遇到“雷暴”,整条循环就停止了,后面就不会继续判断了。

var 天气 = ["晴朗","阴天","下雨","雷暴","台风"]
for i in 天气 {
    switch i {
    case "晴朗":
        print("可以出门")
    case "阴天":
//        print("可以出门")
        fallthrough
    case "下雨":
        print("带伞出门")
    default:
        print("在家上网!")
    }
}

在本段代码中,fallthrough使本段代码直接交给下一条case处理。使得“阴天”这条case也会打印“带伞出门。”

小结与预告

掌握了流程控制,我们就可以对数据进行操控了。编程的本质,无非是一系列的假设,判断,循环等等。
我们可以利用已经学到的知识,写很多东西了。比如,

来点小提示:

  1. 算术运算符处理数字
  2. if或switch判断分数的范围
  3. 用while循环包住一个if判断,在其中进行变量的增减操作
上一篇下一篇

猜你喜欢

热点阅读