Ekulelu's Blog

Swift4学习笔记5——流程控制语句

if else语句

if语句和其他语言中的使用是一样的,只是语法稍有不同。首先是不用括号,其次是即使是if后面只有一条语句,也必须加上大括号。

1
2
3
4
5
6
var array1 = ["a","b","c"]
if array1.count > 1 {
print("array1 is not empty") //这句会打印出来
} else {
print("array1 is empty")
}

还记得可选类型吗,if语句可以用来检测可选类型是否为空.

1
2
3
4
5
6
var str : String?
if let s = str {
print("str is not nil")
} else {
print("str is nil") //这句会打印
}

for 语句

Swift3中移除了传统C语言里面的for循环,就像下面那种

1
2
3
for var index = 0; index < 3; index++ { //已经移除
print(index)
}

for-in 语句

这个语句感觉在swift里面用得很爽,尤其是用来遍历集合。集合类的遍历方法请看我上一篇关于集合的文章。

1
2
3
for index in 1...3 {
print(index)
}

上面的只能是每次加1,但是现在可能有需求每次增加的不是1,所以现在有了这个:

1
2
3
4
for tickMark in stride(from: 0, to: 60, by: 5) {
print(tickMark)
// 打印 (0, 5, 10, 15 ... 45, 50, 55)
}

while语句和 repeat-while语句

把括号去掉就行了

1
2
3
4
5
6
7
8
9
10
11
var index = 3
while index > 0 {
index--
print(index)
}
index = 3
repeat {
index--
print(index)
} while index > 0

Break和continue

这个用法和C里面没差,不举例了

Switch语句

最多东西的一个。Swift里面的Switch语句不仅可以判断整形,而且还可以判断各种类型。注意的是执行了一个case后是不会继续往下面执行的,也就是不用添加break语句。相反如果你想要继续往下执行,你必须在这个case最后加上Fallthrough。另外就是default,对于不是枚举类型的变量,defalut必须加上。枚举类型的变量在完全枚举的时候才可以省略default。

1
2
3
4
5
6
7
8
9
10
11
12
var str = "a"
switch str {
case "a":
print("a") //这句会打印
fallthrough
case "b":
print("b") //这句会打印
case "c":
print("c") //不会打印
default:
print("nil") //不会打印
}

switch里面一个case可以对应多个选项,每个选项之间用逗号分开。这个用法是用来实现c里面的某个选项里面没有执行代码的情况。Swift不允许某个选项里面没有可执行的代码。

1
2
3
4
5
6
7
var str = "s"
switch str {
case "a","s":
print("a") //只打印这句
default:
print("nil")
}

case里面也可以是一个范围,在每个case之间的范围有重叠的话,只会匹配第一个

1
2
3
4
5
6
7
8
9
var i = 2
switch i {
case 1...10:
print("1-10") //只打印这句
case 9..<20:
print("10-20") //因为匹配了第一句,所以这句不会再匹配
default:
print("other")
}

对Tuple 的匹配
你可以匹配Tuple的两个值,也可以只匹配一个值,还可以匹配范围

1
2
3
4
5
6
7
8
9
10
11
12
//下面case的条件都是可以匹配的,把前面的case注释掉的话就会匹配下一个case。
var tuple = (2,1)
switch tuple {
case (2,1):
print("(2,1)") //因为自动添加break的机制,所以不会往下走
case (let x,1): //可以用变量来自由化其中一个值,只需要另外一个值匹配了,就会匹配这个。如果你不关注x的值,你也可以把x换为_
print("x = \(x)")
case (-1...3,0...4):
print("(-1~3,0~4)")
default :
print("other")
}

Where语句在switch中

where可以用来进一步对case添加约束

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var tuple = (2,1)
switch tuple {
case var (x,y) where x == y: //这里用var 和 let 区别在于能不能在case里面修改解包的x,y值。但是即使修改也不会影响原来的tuple
print("x == y")
case let (_,x) where x == 4:
print("x == 4")
case var (x,y) where x != y: //匹配了这个case
print("x != y") //打印 x != y
x = 1
print(x) //打印 1
default :
print("other")
}
print(tuple) //打印 (2,1)

Labeled Statements

这个labeled statements就像goto语句,但是跳转比较有限,只能用于循环里面。虽然switch也可以加上去,但是并没有用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var tuple = (2,1)
second:for _ in 0... {
frist : switch tuple { //这个first并没有什么用
case var (x,y) where x == y: //这里用var 和 let 区别在于能不能在case里面修改解包的x,y值。但是即使修改也不会影响原来的tuple
print("x == y")
break second
case var (x,y) where x != y: //匹配了这个case
print("x != y") //打印 x != y
tuple = (1,1)
continue second
default :
print("other")
}
}
//上面的for循环依次打印了 x != y x == y
//注意下面的second,虽然前面也定义了,但是不会冲突。循环内的跳转只能针对循环
second:repeat { //对于while也是可以用。
frist : switch tuple { //这个first并没有什么用
case var (x,y) where x == y: //这里用var 和 let 区别在于能不能在case里面修改解包的x,y值。但是即使修改也不会影响原来的tuple
print("x == y")
break second
case var (x,y) where x != y: //匹配了这个case
print("x != y") //打印 x != y
tuple = (1,1)
continue second
default :
print("other")
}
} while true
//while循环只打印了 x == y,因为Tuple已经被修改为(1,1)

Assertion和Precondition

1
assert(_:_:file:line:)

判断一个情况是否为true,不为true直接停止程序。

1
2
var i=1
assert(i > 10)

如果你通过其他判断语句已经知道了当前的条件已经不符合需求了,那么可以用下面的语句直接结束程序。

1
assertionFailure(_:file:line:)

Swift现在多了一个Preconditions,区别文档上说的是开发时候用Assertions,生产用Preconditions。(Assertions help you find mistakes and incorrect assumptions during development, and preconditions help you detect issues in production. )

1
2
precondition(_:_:file:line:)
preconditionFailure(_:file:line:)

文档上有两段话:
If you compile in unchecked mode (-Ounchecked), preconditions are not checked. The compiler assumes that preconditions are always true, and it optimizes your code accordingly. However, the fatalError(:file:line:) function always halts execution, regardless of optimization settings.
You can use the fatalError(
:file:line:) function during prototyping and early development to create stubs for functionality that hasn’t been implemented yet, by writing fatalError(“Unimplemented”) as the stub implementation. Because fatal errors are never optimized out, unlike assertions or preconditions, you can be sure that execution always halts if it encounters a stub implementation.
但是没找到这个-Ounchecked模式,到时有一个选项是disable_safty_checks。
这个选项的关闭和Swift_OPTIMIZATION_LEVEL的模式有关系。如果你选择的是 -Onone,那么不管disable_safty_checks的值,都会检测precondition和assert。但是如果开启了优化,那么assert就再不检测,而precondition就会根据是否关闭安全检测来执行。

guard语句

这个和assertions差不多,都是用来做判断的,不过这个要自己加上处理。用来在条件不满足的情况下跳出方法或循环。

1
2
3
4
5
6
7
var i = 1
while true {
guard i > 1 else {
print("i <= 1")
break //else里面必须加上break或return
}
}

available

用来判断是否可以使用某个版本API

1
2
3
4
5
if #available (iOS 8, OSX 10.10, *) { //括号里面表示的是最低的版本。这个*必须有,代表其他平台
} else {
}