多个可选类型组合在一起调用就会形成可选链条。
一、可选链(Optional Chaining)
1.1. 什么是可选链
示例代码:
1 | class Car { var price = 0 } |
正常调用:
1 | var person: Person = Person() |
如果把
person
对象修改为可选类型:系统提示要想用可选类型对象引用成员必须强制解包或添加
?
:按照提示修改代码,编译通过:
1
2
3
4
5var person: Person? = Person()
var age = person?.age()
var age1 = person!.age()
var name = person!.name = "idbeny"
var index = person?[6]
age
是可选类型Int?
,打印Optional(30)
age1
是Int
类型,打印18
name
是可选类型String?
,打印Optional("idbeny")
index
是可选类型Int?
,打印Optional(6)
- 函数返回值:如果
1
2func getName() -> String { "idbeny" }
person?.name = getName()person
是nil
,就不会调用函数getName()
。
总结:
- 如果可选项为
nil
,调用方法、下标、属性失败,结果为nil
- 如果可选项不为
nil
,调用方法、下标、属性成功,结果会被包装成可选项 - 如果结果本来就是可选项,不会进行再次包装
1.2. 可选项绑定
对象调用函数,是可以用一个变量去接受的,即使函数没有返回值:
1 | var result = person?.eat() |
result
是什么呢?如果person
是nil
,result
就是nil
;如果person
不为nil
,则返回一个空元祖(因为Void
本质就是一个空元祖)。
怎样知道eat
函数是否调用成功?可以使用可选项绑定进行解包判断:
1 | if let _ = person?.eat() { |
1.3. 可选链
多个?
可以链接在一起形成可选链代码:
1 | var dog = person?.dog // Dog? |
如果链中任何一个节点是nil
,那么整个链就会调用失败。可选链最终返回的都是可选类型(不强制解包的情况下)。
二、可选链应用
示例代码一:
1 | var scores = ["idbeny": [10, 20, 30], "1024星球": [66, 88, 99]] |
字典取值都是可选类型,因为key
有可能为nil
。所以字典取值一般加上一个?
,尽量不要使用!
强制解包,防止取出的值是nil
。
示例代码二:
1 | var num1: Int? = 5 |
num1? = 10
意思是如果num1
不为nil
,就把10赋值给num1
,并且包装为可选类型。
num2? = 10
意思是如果num2
为nil
,后面的代码就不会执行。
示例代码三:
1 | var dict: [String: (Int, Int) -> Int] = [ |
(+)
是把两个参数相加并返回的意思,是编译器的语法糖。字典取值如果是函数,该函数也会被包装成可选类型,所以需要?
调用函数,但是最终函数返回值是可选类型。