今天开始跟新下。争取过年回家前全部学完。
今天来说下swift中比较重要,当然也是比较简单的控制流。啥是控制流,控制流就是if
else
switch case
while
do
还有swif里面特殊且很有用的for-in
等之类。你说是不是很简单。稍有其他语言基础的这一节来说都非常容易。
OK,进入正题。
swift中for
语句和其他语言的for语句没什么异样,都是用来循环的。循环次数啊,数组啊,对象啊,字典啊,或者字符串等,值得一提的是swift中又多了一种for-in
循环。和javascript中语法差不多,一般用来循环区间,那先说说for in
吧。
你可以使用for-in循环来遍历一个集合里面的所有元素,例如由数字表示的区间、数组中的元素、字符串中的字符等
看第一个例子:循环出1-5分别乘以5的结果。
for i in 1...5 {
println("\(i)*5=\(i*5)");
}
//输出结果
1*5=5
2*5=10
3*5=15
4*5=20
5*5=25
这个时候,用for in
就特别快的就循环出了结果。你可能注意到了1...5
这样一种区间表示形式。这是swift中的一种闭区间操作符,表示从1到5的区间之间的数字。一点超级赞,比PHP还好一些。
这里的i
和其他语言中的语法一样,是一个内部的临时的,不过在swiftl中它是一个临时常量,对,没错,在swift中i是一个常量,当然你也可以当做变量来对待。所以,如果,你没提前申明i, 就像上面的这样子循环,然后打印出i是会报错的。当然即使你提前申明了i=0,那么后面打印的是时候它还是0,不会变成5
还有一种情况是,for-in
的i
我根本不想用它,或者不想看到它,我仅仅是想循环而已,那么可以用_
替代i
。看一个例子。
let base = 3
var answer = 1
for _ in 1...10 {
answer *= base
}
println("\(base) 的 10 次方 is \(answer)")
//3 的 10 次方 is 59049
当然上面的_
替换成i
也是同样可以的。
我们继续深挖for-in
模式。之前几节中,我们学习了数组,也简单的提到过for。这里再着重看下。用for-in
来循环数组。看下面这个例子:
var fruit = ["apple","orange","tomorrow","banana"];
for i in fruit {
println(i);
}
//输出
apple
orange
tomorrow
banana
既然数组可以循环,那么字典也应该循环,前面几节说到字典的时候,也提到过for-in
循环,由于字段是key-value
形的,所有,这个时候for-in
就要应该有2
个参数来并用()
括起来循环了。这里再继续举例子温习下:
var student = ["name":"tony","age":18,"gender":1];
for (key, value) in student {
println("student info is \(key) : \(value)");
}
//输出
student info is name : tony
student info is age : 18
student info is gender : 1
同样,for-in
也可以用来循环字符串,变成一个一个的字符:
var info = "abcdef";
for character in info {
println(character);
}
//输出
a
b
c
d
e
f
for就更容易理解和掌握了,swift中的for
和其他语言中差不多,都是用来循环使用的,只不过书写形式与其他语言不太一样,没有用括号()
给括起来。看个例子:
for var index = 0; index < 3; index++ {
println("index is \(index)")
}
// index is 0
// index is 1
// index is 2
对不对,和其他语言中几乎一模一样吧。就是这种书写形式有点怪不习惯,写多也就差不多了。
说到这,那我们看下,其他语言中for
循环是如何书写的:
php:
for ($index = 0; $index < 3; $index++) {
echo $index;
}
javascript:
for (var index = 0; index < 3; index++) {
console.log(index);
}
C:
for (int index = 0; index < 3; index++) {
println(index);
}
所以,你看,是不是很简单的。
while 循环也是非常简单的,如果你学过其他的语言,对while循环也不会陌生,swift中while和其他语言也几乎一样,不同的也只是少了()
而已。while
循环的格式如下:
while condition {
statements
}
那看个例子,一个数自减,少于4就停止:
var istrue = true;
var num = 10;
while istrue {
num--;
if num < 4 {
istrue = false;
}
println(num);
}
//输出
9
8
7
6
5
4
3
所以,while
的循环是先判断true
或者 false
,再去执行语句。
do-while
就更简单了。相比while
,它是先执行一次,再去判断,所以是会比while
多执行一次的。但是依然是和其他语言中的一样, 它的书写形式是这样的:
do {
statements
} while condition
我们还是看刚才while
的那个例子,来用do - while
来写一遍:
var istrue = true;
var num = 10;
do {
num--;
if num < 4 {
istrue = false
}
println(num)
} while istrue
//输出
9
8
7
6
5
4
3
swift中提供了几种条件判断语句,if else switch
,和其他的语言一样,都是用来判断条件并执行对应的语句
if 语句很简单,和其他的语言一样,只是又少了括号而已。o(╯□╰)o
直接来看例子吧:
var height = 155;
if height < 170 {
println("身高太矮了!");
}
//打印
身高太矮了!
if
通常和 else
搭配其他用,用来表示和if相反的条件成立:
var height = 175;
if height < 170 {
println("身高太矮了!");
} else {
println("身高符合要求!");
}
//打印
身高符合要求!
如果,有好几种条件判断,那么单纯的 if
和 else
就不够用了。所以这个时候又出现了else if
,它用来加一层对立面判断:
var height = 170;
if height < 130 {
println("滚粗")
} else if height < 160 {
println("勉强接受")
} else if height < 180 {
println("完美身高")
}
//打印
勉强接受
其他,我们也可以和&&
或者||
来配和if else
构成一个区间内的取值来条件判断使用:
var age = 16;
if age < 16 {
println("未成年!")
} else if age >= 16 && age < 20 {
println("少年")
} else if age >= 20 && age < 35 {
println("青年")
}
//输出
少年
if 很简单,当然switch 也不难,学过其他语言的,也会对swift中的switch也很熟悉,它也是一个条件判断语句,只不过这个条件判断看着更舒服更清晰,值得一提的是我们使用其他语言中的switch时,经过会忘记加 break
,导致后面几个case 并不匹配的条件也被执行了,就会导致BUG产生。
但是swift非常聪明,它合理的避开个这个问题,即使你没加上 break ,后面其他的case 也不会被执行。永远只会匹配一个case
。 这个很赞! 而且 case 后面的语句更加强大。
swift 的 switch 书写形式如下:
switch some value to consider {
case value 1:
respond to value 1
case value 2,value 3:
respond to value 2 or 3
default:
otherwise, do something else
}
我们举个例子来看下:
var gender = 1;
switch gender {
case 1:
println("男的")
case 0:
println("女的")
default:
println("人妖")
}
你看我们是没加break
的。执行结果任然只是"男的"; 只会匹配一个case, 不会打印出"女的"。这一点设计的很赞啊有没有!!!
那你说,有时候我的一些变态需求就是希望它执行下面的case,咋办!有办法,有一个关键字 fallthrough
叫贯穿,只是使用它就可以继续下面的case了,这个我们下面说。
上面说了,swift的switch
的case
很强大,它不仅仅能单一匹配,而且还能各种区间或者多个匹配,下面来来一一看下。
所以下面的这个是会自己报错的,因为,case 是单匹配的,所以,它每一个 case 分支都必须包含至少一条语句:
let anotherCharacter: Character = "a"
switch anotherCharacter {
case "a":
case "A":
println("The letter A")
default:
println("Not the letter A")
}
// 会报编译错误。
let someCharacter: Character = "e"
switch someCharacter {
case "a", "e", "i", "o", "u":
println("\(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":
println("\(someCharacter) is a consonant")
default:
println("\(someCharacter) is not a vowel or a consonant")
}
// 输出 "e is a vowel"
在这个例子中,第一个 case 分支用于匹配五个元音,第二个 case 分支用于匹配所有的辅音。
牛逼不?一个case可以匹配这么多。大赞啊。
前面讲for
循环时候,讲到闭合区间1...100
这种形式,表示从1到100的数字区间,case 也可以用,只不过不用加in
了:
let people_num = 1000;
var naturalCount: String
switch people_num {
case 0:
naturalCount = "没人"
case 1...3:
naturalCount = "3人以内"
case 4...9:
naturalCount = "4到9个人"
case 10...99:
naturalCount = "10到99人"
case 100...999:
naturalCount = "100到999人"
case 1000...9999:
naturalCount = "1000到9999人"
default:
naturalCount = "人太他妈的多了"
}
println("There are \(naturalCount)")
//输出
//There are 1000到9999人
这个功能确实蛮使用和蛮强大的。
元祖
还记得是啥不?我们第一节就讲过它,它用()
把几个不同类型的数值组合起来,在case中它居然也能用到,看个例子:
let somePoint = (1, 1)
switch somePoint {
case (0, 0):
println("(0, 0) is at the origin")
case (_, 0):
println("(\(somePoint.0), 0) is on the x-axis")
case (0, _):
println("(0, \(somePoint.1)) is on the y-axis")
case (-2...2, -2...2):
println("(\(somePoint.0), \(somePoint.1)) is inside the box")
default:
println("(\(somePoint.0), \(somePoint.1)) is outside of the box")
}
// 输出 "(1, 1) is inside the box"
这个例子中,我们用元祖来表示一个坐标,然后用case 来匹配。是不是很强大啊。你看。
上面说到了case 可以匹配元祖,其实在匹配的过程中,还能将匹配到的这个值给绑定到另一个值上,以备用,这就叫值绑定。需要搭配let
或者var
来申明匹配到的值来使用
var point = (1, 1);
switch point {
case (var x, 0):
println("匹配到x为\(x)")
case (0, var y):
println("匹配到y为\(y)")
case var (x, y):
println("匹配到x为\(x)y为\(y)")
}
//输出
//匹配到x为1y为1
这个例子,不仅匹配到了条件,还把匹配到值给取到了,有点像正则匹配对吧。
我们继续深挖case。我们任然可以在匹配的时候,再加条件判断,以达到更加精准,所以可以用where
语句来判断下:
let yetAnotherPoint = (1, -1)
switch yetAnotherPoint {
case let (x, y) where x == y:
println("(\(x), \(y)) is on the line x == y")
case let (x, y) where x == -y:
println("(\(x), \(y)) is on the line x == -y")
case let (x, y):
println("(\(x), \(y)) is just some arbitrary point")
}
// 输出 "(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
我们还是举上面的例子,来说明下:
var gender = 1;
switch gender {
case 1:
println("男的")
fallthrough
case 0:
println("女的")
default:
println("人妖")
}
//输出
男的
女的
上面我们在case 1
后面加了一个fallthrough
意思就是说:希望它往下贯穿,不要停止。所以输出就是“男的 女的”了。当然,值得注意的是,这个贯穿,只能穿一次,所以你如果想把“人妖”给打出来,可以在 case 2 后面再加一个fallthrough
。
终于把控制流学完了。太他妈不容易了!%>_<%