初学Swift的时候,被! 和 ? 整懵了,为什么这些类型后面要加个问号,乱七八糟的,不过只要写错了,xcode就会给出提示,修改后就没问题了。一直都没有深入研究。这几天研究了一下这个可选类型,发现这个东西真的好。
在我看来,可选类型是为了安全而出现的。它避免了空指针异常这种情况。比如:
` var str : String`
声明一个String类型的str,没有给它赋初值,这句话是没有问题的。但是当我们使用它的时候,比如:
str.uppercaseString
就会有空指针异常,而且这个问题在OC或者JAVA里,只有在运行时才会崩溃,而在Swift里引用了可选类型,就可以在编译时就给出警告,这就是我理解的可选类型的意义。
可选类型改写上面的代码:
var str : String?
str?.uppercaseString
第一行代码,在类型后面加一个?,说明这是一个可选类型,可选类型可以说是该类型的超集,包括String类型和一个nil值。
第二行代码,在调用方法前加一个?,该句的作用是如果str为nil,那么不执行后面的语句,如果不为nil,才执行uppercaseString,这被称为可选类型的链式操作,这有效避免了空指针异常,保证运行时安全。
还有一个概念是解包(unwrap)
可选类型是不可以直接使用的,比如:
var str : String? = "abc"
let str2 = str
会报错,因为str是可选类型,你必须拆包后才能使用它的值,加一个 感叹号 !,这就是解包!
let str2 = str!
告诉编译器,这个值肯定是存在而不是nil的。有人说,诶,这不就不安全了么,我怎么知道它是不是nil啊,没错。所以这种写法不推荐,除非你确定这个值肯定不为nil。
那么,这种写法应该更安全些:
var str : String? = "abc"
if let str2 = str{
print(str2)
}
这种if let 语句,判断str是否为 nil,如果不为nil,执行括号内代码,否则执行else
不过有人会说了,这样好麻烦,写代码好累。确实,为了安全是要牺牲一些东西的,原来为了省钱,总是把电动车停在收费停车场外面,直到电瓶被偷才追悔莫及,所以为了安全,请交一块钱停车费吧。
况且,苹果还提供了更加方便的代码来使用:
var str2 = str == nil ? "error" : str!
三目运算符,如果为nil,则给str2赋“error”
还有更简单的
var str2 = str ?? "error"
效果是相同的,推荐使用第二个。
除此之外,还有一种隐式可选型:
var str : String!
它在使用时不用解包,直接使用
str.uppercaseString
可见这种用法并不安全,所以它的使用率不是很高,通常在类的声明里使用,比如,在类的在init()中不想对某个变量初始化,就加一个!,具体怎么使用再慢慢深究吧。