读《函数式Swift》笔记

读《函数式Swift》笔记:Swift可选值

可选链

可选绑定

定义一个函数,接受两个可选整数相加,返回一个可选整数。但是加法运算符只支持非可选的值。
所以我们可以对Int?进行可选绑定。

1
2
3
4
5
6
7
8
func add(_ optionalX: Int?, _ optionalY: Int?) -> Int? {
if let x = optionalX {Â
if let y = optionalY {
return x + y
}
}
return nil
}

我们可以换一种简单的方式:同时绑定多个可选值

1
2
3
4
5
6
func add2(_ optionalX: Int?, _ optionalY: Int?) -> Int? {
if let x = optionalX, let y = optionalY {
return x + y
}
return nil
}

还可以用更简单的方式,可以使用一个 guard 语句,当值缺失时提前退出:

1
2
3
4
func add3(_ optionalX: Int?, _ optionalY: Int?) -> Int? {
guard let x = optionalX, let y = optionalY else { return nil }
return x + y
}

下面来个实际的例子,要分别从两个字典中取值,编写一个能返回指定国家首都人口的函数。
我们定义了下面这两个字典,国家与其首都相关联,城市和其对应的人口相关联:

1
2
3
4
5
6
7
8
9
10
11
12
let capitals = [
"France": "Paris",
"Spain": "Madrid",
"The Netherlands": "Amsterdam",
"Belgium": "Brussels"
]
let cities = ["Paris": 2241, "Madrid": 3165, "Amsterdam": 827, "Berlin": 3562]
func populationOfCapital(country: String) -> Int? {
guard let capital = capitals[country], let population = cities[capital]
else { return nil }
return population * 1000
}

分支上的可选值

为了在switch语句中匹配可选值,可以为case分支中的每个模式添加一个?后缀:

1
2
3
4
5
6
switch madridPopulation {
case 0?: print("Nobody in Madrid")
case (1..<1000)?: print("Less than a million in Madrid")
case let x?: print("\(x) people in Madrid")
case nil: print("We don't know about Madrid")
}