声明一个可选的对象
var str: String? = "asdfasdf" //str是一个可以设置nil的String //enum Optional{case None case Some} str = nil let i: Int? //如果声明的时候不赋值,默认就是nil //str.startIndex//会报错,因为此时str不是一个真正的String,所以没有startIndex //两种情况解决optional的问题 //第一种 //str!.startIndex //强制解封变为String //第二种,optional binding if let s = str { print("(s)") } else { print("str 是nil值") } var str2: String! = "sadf" //称之为隐式的解封(implicitly unwrapped) str2 = nil str2.startIndex//报错
在swift中是不允许变量赋值为nil 也就是其他语言中的 null 空值 因为造成程序错误的大多数是空指针异常
但是可选变量可以赋值为nil 因为他相当于把当前类型变量与nil值做了一个封装 变成一个拥有两个成员的对象
使用时需要进行解封 前面一种用流程空值语句判断可行 但太繁杂 而!强制解封一旦解封出来的变量值是nil 程序就会出错
最后的隐式解封声明方式也比较鸡肋 一旦该变量赋值为nil 再次访问则会报错
最安全的访问解封方式是问号? 前面代码最后一句访问时变成
str2?.starIndex
则如果str2是nil值就直接无视 不会因为错误而终止程序
可选链
我们定义三个类,并将一个类封装进另一个类再封装进另一个类(有点晕,看代码)
class Person { var ci: ClassInfo? } class ClassInfo { var t:Teacher? } class Teacher { var name = "hello" }
我们实例化一个Person并访问其属性对其进行实例化
let p = Person() let ci = ClassInfo() ci.t = Teacher() p.ci = ci p.ci.t.name//报错
为什么会报错呢?因为类的定义中 ci 和 t 的属性都是可选的 不进行解封是无法使用的 访问方式就变成了这样
p.ci?.t?.name
当然也能使用强制解封 不过如果某一个可选属性是nil则程序会终止
p.ci!.t!.name //可以强制解封
最后一种可选绑定安全的一种
if let n = p.ci?.t?.name { //也可以用可选绑定 print(n) }
这个表达式的意思是对n进行赋值操作 如果等号右边取出的值最终为nil 则会赋值失败(没加可选的变量是无法赋值为nil的) 表达式返回false
可选链有以下几点
1.可选链一定要是可选的
2.返回的总是一个可选的
3.可以设置值(并非只能访问)
4.可以访问方法,即使方法无返回值