swift 可选类型
swift可选类型
1、源码定义:
enum Optional<Wrapped> {
case none
case some(Wrapped)
}
可选型就是一个枚举,当Wrapped有值时,走some流程,其值就是Wrapped的值。
若wrapped没有值,就走none流程,什么都没有,就是nil
2、声明
var age: Int?
var num: Optional<Int>
3、可选类型解包
可选类型就像一个薛定谔容器一样,解包之前不知道是不是有有效值。
例如
var a: Int? = 10
Var b: Int? = 5
Var sum:Int = a + b
这里的加法 a+b 是不成立的,因为实际上是Optional(10) + Optional(5)
4、解包分为强制解包, 可选项解包
强制解包:不管内部有没有值,直接解包。若内部没有值,直接解包,程序会崩溃。
4.1、强制解包的方式:
一般在可选值后面加感叹号
Var sum : Int = a! + b!
这种方式看似简洁,但是会忽略编译器警告,并且结果为nil时会直接闪退。
当确定某个值不可能是nil时,使用强制解包。
若存在没值的情况,不能使用强制解包。一旦解包,程序会崩溃。
4.2 可选解包
先做是否有值判断,若没有值,就返回nil,否则就返回真实值。
两种方式:
- if let : 如果有值,则会进入if流程
- guard let: 如果为 nil,则进入else流程。
If-let:语句,检查可选值是否为nil,如果不是nil, 便会解包可选值。
if let num = num1 {
print(num)
}else {
//值为nil
}
Guard - let:
guard 刚好时if not let 的意思。可选包为nil的情况,走gurad的else部分,一般直接返回。正常流程继续执行。
func test(value: Int) {
guard let v = value else{
return
}
//不为nil流程
print(v)
}
4.3 隐式解包:
隐式解包,是在声明类型的时候,加上感叹号!,区别强制解包。
这种方式声明的变量在使用的时候,系统会强制解包,可不是可选类型。一旦值为nil, 使用的时候依然会程序崩溃。
例如:
let num: Int! = 2 //Int! 依然是可选类型
num += 1 //3
系统强制解包nun, 如果num 为nil, 就会崩溃。
避免可能的程序崩溃有两种方式:
1、确定隐式解包没有nil的情况。就可以放心的使用。
2、若存在nil的情况,使用可选解包。
例如:
if let tempNum = num {
tempNum += 1
}
5、可选值绑定
使用可选绑定(optional binding)来判断可选类型是否包含值,如果包含就把值赋值给一个临时常量或者变量。在可选类型中,我们已经使用了可选值绑定
if let num = num1 {
//业务代码
}
Guard let v = num2 else {
return
}
//业务代码
6、Objective-C中的nil与swift中的nil的区别
OC: nil是一个指向不存在对象的指针,只有对象类型才能赋值为nil
Swift: nil不是指针,是一个确定的值,任何类型的可选状态都可以设置为nil,不只是对象类型。
OC: nil只对类(class)有用
Swift: 可选类型对所有的类型都可用且更安全
OC: 向nil对象发送消息是安全的,不会崩溃(delegate?.handle()//delegate如果为nil,handle将不会被执行)
Swift: 可通过可选链实现
Optional可以有值,也可以没有值,没有值的时候就是nil。
此外,Swift的nil也和Objective-C有些不一样,在Objective-C中,只有对象才能为nil,而在Swift里,当基础类型(整形,浮点型,布尔型)没有值时,也是nil,而不是一个初始值,没有初始值是不能使用的。
Optional类型的值和普通的非Optional值的区别就在于:Optional值未经初始化虽然为nil,但普通变量连nil值都没有。
//未被初始化,但是时一个Optional类型,为nil
var str: String?
str //nil
//未被初始化,也不是Otional类型
Var str2: String
str2 //使用出错