[关闭]
@phper 2016-08-12T11:39:42.000000Z 字数 6389 阅读 3403

swift 7 控制流

swift


之前说完了swift中的基本数据结构,基本语法,以及字符串、数组、字典,今天看了下貌似又过去好久没有跟新swift了,罪过啊。

今天开始跟新下。争取过年回家前全部学完。

今天来说下swift中比较重要,当然也是比较简单的控制流。啥是控制流,控制流就是if else switch case while do 还有swif里面特殊且很有用的for-in 等之类。你说是不是很简单。稍有其他语言基础的这一节来说都非常容易。

OK,进入正题。

循环语句

swift中for语句和其他语言的for语句没什么异样,都是用来循环的。循环次数啊,数组啊,对象啊,字典啊,或者字符串等,值得一提的是swift中又多了一种for-in循环。和javascript中语法差不多,一般用来循环区间,那先说说for in吧。

for - in

你可以使用for-in循环来遍历一个集合里面的所有元素,例如由数字表示的区间、数组中的元素、字符串中的字符等

看第一个例子:循环出1-5分别乘以5的结果。

  1. for i in 1...5 {
  2. print("\(i)*5=\(i*5)");
  3. }
  4. //输出结果
  5. 1*5=5
  6. 2*5=10
  7. 3*5=15
  8. 4*5=20
  9. 5*5=25

这个时候,用for in 就特别快的就循环出了结果。你可能注意到了1...5这样一种区间表示形式。这是swift中的一种闭区间操作符,表示从1到5的区间之间的数字。一点超级赞,比PHP还好一些。

这里的i和其他语言中的语法一样,是一个内部的临时的,不过在swift中它是一个临时常量,对,没错,在swift中i是一个常量,当然你也可以当做变量来对待。所以,如果,你没提前申明i, 就像上面的这样子循环,然后打印出i是会报错的。当然即使你提前申明了i=0,那么后面打印的是时候它还是0,不会变成5

还有一种情况是,for-ini我根本不想用它,或者不想看到它,我仅仅是想循环而已,那么可以用_替代i。看一个例子。

  1. let base = 3
  2. var answer = 1
  3. for _ in 1...10 {
  4. answer *= base
  5. }
  6. print("\(base) 的 10 次方 is \(answer)")
  7. //3 的 10 次方 is 59049

当然上面的_替换成i也是同样可以的。

我们继续深挖for-in模式。之前几节中,我们学习了数组,也简单的提到过for。这里再着重看下。用for-in来循环数组。看下面这个例子:

  1. var fruit = ["apple","orange","tomorrow","banana"];
  2. for i in fruit {
  3. print(i);
  4. }
  5. //输出
  6. apple
  7. orange
  8. tomorrow
  9. banana

既然数组可以循环,那么字典也应该循环,前面几节说到字典的时候,也提到过for-in循环,由于字段是key-value形的,所有,这个时候for-in就要应该有2个参数来并用()括起来循环了。这里再继续举例子温习下:

  1. var student = ["name":"tony","age":18,"gender":1];
  2. for (key, value) in student {
  3. print("student info is \(key) : \(value)");
  4. }
  5. //输出
  6. student info is name : tony
  7. student info is age : 18
  8. student info is gender : 1

同样,for-in也可以用来循环字符串,变成一个一个的字节:

  1. var info = "abcdef";
  2. //swift 1 中
  3. for character in info {
  4. println(character);
  5. }
  6. //swift 2中得用 info.characters,不然报错
  7. for character in info.characters {
  8. print(character);
  9. }
  10. //输出
  11. a
  12. b
  13. c
  14. d
  15. e
  16. f

for

for就更容易理解和掌握了,swift中的for 和其他语言中差不多,都是用来循环使用的,只不过书写形式与其他语言不太一样,没有用括号()给括起来。看个例子:

  1. for var index = 0; index < 3; index++ {
  2. println("index is \(index)")
  3. }
  4. // index is 0
  5. // index is 1
  6. // index is 2

对不对,和其他语言中几乎一模一样吧。就是这种书写形式有点怪不习惯,写多也就差不多了。

说到这,那我们看下,其他语言中for循环是如何书写的:

php:

  1. for ($index = 0; $index < 3; $index++) {
  2. echo $index;
  3. }

javascript:

  1. for (var index = 0; index < 3; index++) {
  2. console.log(index);
  3. }

C:

  1. for (int index = 0; index < 3; index++) {
  2. println(index);
  3. }

所以,你看,是不是很简单的。

while

while 循环也是非常简单的,如果你学过其他的语言,对while循环也不会陌生,swift中while和其他语言也几乎一样,不同的也只是少了()而已。while循环的格式如下:

while condition {
statements
}

那看个例子,一个数自减,少于4就停止:

  1. var istrue = true;
  2. var num = 10;
  3. while istrue {
  4. num--;
  5. if num < 4 {
  6. istrue = false;
  7. }
  8. print(num);
  9. }
  10. //输出
  11. 9
  12. 8
  13. 7
  14. 6
  15. 5
  16. 4
  17. 3

所以,while的循环是先判断true 或者 false ,再去执行语句。

repeat - while

repeat-while 是swift 2中修改 do -while的, 用法和do-while一样。相比while,它是先执行一次,再去判断,所以是会比while多执行一次的。但是依然是和其他语言中的一样, 它的书写形式是这样的:

repeat {
statements
} while condition

我们还是看刚才while的那个例子,来用repeat - while来写一遍:

  1. var istrue = true;
  2. var num = 10;
  3. repeat {
  4. num -= 1;
  5. if num < 4 {
  6. istrue = false
  7. }
  8. print(num)
  9. } while istrue
  10. //输出
  11. 9
  12. 8
  13. 7
  14. 6
  15. 5
  16. 4
  17. 3

条件语句

swift中提供了几种条件判断语句,if else switch,和其他的语言一样,都是用来判断条件并执行对应的语句

if

if 语句很简单,和其他的语言一样,只是又少了括号而已。o(╯□╰)o

直接来看例子吧:

  1. var height = 155;
  2. if height < 170 {
  3. print("身高太矮了!");
  4. }
  5. //打印
  6. 身高太矮了!

if 通常和 else 搭配其他用,用来表示和if相反的条件成立:

  1. var height = 175;
  2. if height < 170 {
  3. print("身高太矮了!");
  4. } else {
  5. print("身高符合要求!");
  6. }
  7. //打印
  8. 身高符合要求!

如果,有好几种条件判断,那么单纯的 ifelse 就不够用了。所以这个时候又出现了else if ,它用来加一层对立面判断:

  1. var height = 170;
  2. if height < 130 {
  3. print("滚粗")
  4. } else if height < 160 {
  5. print("勉强接受")
  6. } else if height < 180 {
  7. print("完美身高")
  8. }
  9. //打印
  10. 勉强接受

其他,我们也可以和&&或者|| 来配和if else构成一个区间内的取值来条件判断使用:

  1. var age = 16;
  2. if age < 16 {
  3. print("未成年!")
  4. } else if age >= 16 && age < 20 {
  5. print("少年")
  6. } else if age >= 20 && age < 35 {
  7. print("青年")
  8. }
  9. //输出
  10. 少年

switch

if 很简单,当然switch 也不难,学过其他语言的,也会对swift中的switch也很熟悉,它也是一个条件判断语句,只不过这个条件判断看着更舒服更清晰,值得一提的是我们使用其他语言中的switch时,经过会忘记加 break,导致后面几个case 并不匹配的条件也被执行了,就会导致BUG产生。

但是swift非常聪明,它合理的避开个这个问题,即使你没加上 break ,后面其他的case 也不会被执行。永远只会匹配一个case。 这个很赞! 而且 case 后面的语句更加强大。

swift 的 switch 书写形式如下:

  1. switch some value to consider {
  2. case value 1:
  3. respond to value 1
  4. case value 2,value 3:
  5. respond to value 2 or 3
  6. default:
  7. otherwise, do something else
  8. }

我们举个例子来看下:

  1. var gender = 1;
  2. switch gender {
  3. case 1:
  4. print("男的")
  5. case 0:
  6. print("女的")
  7. default:
  8. print("人妖")
  9. }

你看我们是没加break的。执行结果任然只是"男的"; 只会匹配一个case, 不会打印出"女的"。这一点设计的很赞啊有没有!!!

那你说,有时候我的一些变态需求就是希望它执行下面的case,咋办!有办法,有一个关键字 fallthrough叫贯穿,只是使用它就可以继续下面的case了,这个我们下面说。

上面说了,swift的switchcase很强大,它不仅仅能单一匹配,而且还能各种区间或者多个匹配,下面来来一一看下。

所以下面的这个是会自己报错的,因为,case 是单匹配的,所以,它每一个 case 分支都必须包含至少一条语句:

  1. let anotherCharacter: Character = "a"
  2. switch anotherCharacter {
  3. case "a":
  4. case "A":
  5. print("The letter A")
  6. default:
  7. print("Not the letter A")
  8. }
  9. // 会报编译错误。

case 多个匹配

  1. let someCharacter: Character = "e"
  2. switch someCharacter {
  3. case "a", "e", "i", "o", "u":
  4. print("\(someCharacter) is a vowel")
  5. case "b", "c", "d", "f", "g", "h", "j", "k", "l", "m",
  6. "n", "p", "q", "r", "s", "t", "v", "w", "x", "y", "z":
  7. print("\(someCharacter) is a consonant")
  8. default:
  9. print("\(someCharacter) is not a vowel or a consonant")
  10. }
  11. // 输出 "e is a vowel"

在这个例子中,第一个 case 分支用于匹配五个元音,第二个 case 分支用于匹配所有的辅音。

牛逼不?一个case可以匹配这么多。大赞啊。

case 区间匹配

前面讲for循环时候,讲到闭合区间1...100这种形式,表示从1到100的数字区间,case 也可以用,只不过不用加in了:

  1. let people_num = 1000;
  2. var naturalCount: String
  3. switch people_num {
  4. case 0:
  5. naturalCount = "没人"
  6. case 1...3:
  7. naturalCount = "3人以内"
  8. case 4...9:
  9. naturalCount = "4到9个人"
  10. case 10...99:
  11. naturalCount = "10到99人"
  12. case 100...999:
  13. naturalCount = "100到999人"
  14. case 1000...9999:
  15. naturalCount = "1000到9999人"
  16. default:
  17. naturalCount = "人太他妈的多了"
  18. }
  19. print("There are \(naturalCount)")
  20. //输出
  21. //There are 1000到9999人

这个功能确实蛮使用和蛮强大的。

case 匹配元祖

元祖还记得是啥不?我们第一节就讲过它,它用()把几个不同类型的数值组合起来,在case中它居然也能用到,看个例子:

  1. let somePoint = (1, 1)
  2. switch somePoint {
  3. case (0, 0):
  4. print("(0, 0) is at the origin")
  5. case (_, 0):
  6. print("(\(somePoint.0), 0) is on the x-axis")
  7. case (0, _):
  8. print("(0, \(somePoint.1)) is on the y-axis")
  9. case (-2...2, -2...2):
  10. print("(\(somePoint.0), \(somePoint.1)) is inside the box")
  11. default:
  12. print("(\(somePoint.0), \(somePoint.1)) is outside of the box")
  13. }
  14. // 输出 "(1, 1) is inside the box"

这个例子中,我们用元祖来表示一个坐标,然后用case 来匹配。是不是很强大啊。你看。

case 值绑定

上面说到了case 可以匹配元祖,其实在匹配的过程中,还能将匹配到的这个值给绑定到另一个值上,以备用,这就叫值绑定。需要搭配let或者var来申明匹配到的值来使用

  1. var point = (1, 1);
  2. switch point {
  3. case (var x, 0):
  4. print("匹配到x为\(x)")
  5. case (0, var y):
  6. print("匹配到y为\(y)")
  7. case var (x, y):
  8. print("匹配到x为\(x)y为\(y)")
  9. }
  10. //输出
  11. //匹配到x为1y为1

这个例子,不仅匹配到了条件,还把匹配到值给取到了,有点像正则匹配对吧。

case where 条件

我们继续深挖case。我们任然可以在匹配的时候,再加条件判断,以达到更加精准,所以可以用where语句来判断下:

  1. let yetAnotherPoint = (1, -1)
  2. switch yetAnotherPoint {
  3. case let (x, y) where x == y:
  4. print("(\(x), \(y)) is on the line x == y")
  5. case let (x, y) where x == -y:
  6. print("(\(x), \(y)) is on the line x == -y")
  7. case let (x, y):
  8. print("(\(x), \(y)) is just some arbitrary point")
  9. }
  10. // 输出 "(1, -1) is on the line x == -y"

上面的例子中,我们不仅值绑定了x和y,而且还用where语句来判断x和y的关系。太牛逼了。

控制转移语句

控制转移语句是啥呢?就是控制条件语句的转移,和其他语言中基本一样,主要是这几个:

continue
break
return
fallthrough

continue 很简单,表示循环的时候跳出本次,继续下一个循环,break 则狠一点,直接退出虽有的循环,return 就是直接返回,下面的语句都不执行了。这3个很简单,就不多说了。着重想说下的就是 fallthrough。

这是swift中有别与其他语言中的一个语法,它的存在前面也说过,是因为swift对switch严格控制了,只会单一匹配一个case,即使不加break,后面的case 也不会被执行。所以为了某些变态需求就是需要贯穿后面所有的,就有了fallthrough

我们还是举上面的例子,来说明下:

  1. var gender = 1;
  2. switch gender {
  3. case 1:
  4. print("男的")
  5. fallthrough
  6. case 0:
  7. print("女的")
  8. default:
  9. print("人妖")
  10. }
  11. //输出
  12. 男的
  13. 女的

上面我们在case 1后面加了一个fallthrough 意思就是说:希望它往下贯穿,不要停止。所以输出就是“男的 女的”了。当然,值得注意的是,这个贯穿,只能穿一次,所以你如果想把“人妖”给打出来,可以在 case 2 后面再加一个fallthrough

终于把控制流学完了。太他妈不容易了!%>_<%

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注