基本了解
在Swift代码会经常看到定义属性或方法参数时类型后面会紧跟一个感叹号( !
)或问号( ?
), 刚开始接触Swift的童鞋就可能不太明白之代表什么意思,一头雾水,开始凌乱了。
本文将带你了解感叹号( ! )与问号( ? )之谜,首先问号( ?
)是可选类型,是用来处理值可能缺失的情况,也就是没有值的情况(也就是OC中NULL); 感叹号( !
)就是与之相反的, 就是一定有值(非可选类型),不存在空值的情况(OC中NULL)。
下面根据不同使用场景来进一步了解感叹号( ! )与问号( ? )之谜
各个场景中的叹号( ! )与问号( ? )
类的属性
class MyClass {
var value: String!
var optionalValue: String? // defaulit is nil, 所有定义为可选类型的,可选值都是nil, 和数据类型没有关系。
}
在MyClass
定义了2个属性:value
和optionalValue
,其中optionalValue
为可选类型;这表示value
在使用之前一定是赋了值的(一定有值),optionalValue
则有可能值缺失。下面先来看看几个代码片段来深入了解感叹号( ! )与问号( ? )之谜
1. 下面代码,在运行时初始化一个MyClass
实例会发生什么呢?
class MyClass {
var value: String!
var optionalValue: String?
init() {
let _ = value.count
let _ = optionalValue?.count // 可选解析
}
}
程序会崩溃,报以下错误Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
value
是非可选类型,必须要有值,从代码中看出value
从赋值过。另外构造函数里的问号( ? )是指可选解析(弱解析),并不是指可选类型,这里要注意了
2. 下面代码,在运行时初始化一个MyClass
实例会发生什么呢?
class MyClass {
var value: String!
var optionalValue: String?
init() {
value = "this is string value."
let _ = value.count
let _ = optionalValue!.count // 强解析
}
}
程序会崩溃,和代码片段1报一样的错误Fatal error: Unexpectedly found nil while implicitly unwrapping an Optional value
大家肯定奇怪了明明value
已经赋值了,为什么还会崩溃,问题出在optionalValue
属性,不知道大家注意了没有,此代码的构造函数中optionalValue
后面是感叹号( ! ),而代码片段1的构造函数中optionalValue
后面是问号( ? )。这里的感叹号( ! )是指强解析,你也可以理解为强制取值,但是optionalValue
至定义后从未赋值过,也就是没有值(特别注意:可选值不是值
),自然也就和代码片段1报一样的错
方法参数
class MyClass {
var value: String!
var optionalValue: String?// defaulit is nil
func hello(_ say: String, to: String?) {
}
}
到这里相信大家对叹号( ! )与问号( ? )有一定的了解,这里就简单说一下:hello
方法中say
参数是非可选类型,to
是可选类型,方法中的非可选类型并不需要显示定义,也就是叹号( ! )可以省略。
总结
- 叹号( ! )根据不同场景有2层意思:非选类型和强解析
- 问号( ? )根据不同场景有2层意思:可选类型和弱解析
- 叹号( ! )使用时如果没有值会导致崩溃,问号( ? )进行强解析时如果没有值会导致崩溃
- 一般来说能否确定有值是定义可选类型还是非可选类型的一项标准
- 可选值不是值
如何正确解析可选类型
方法1
guard let realValue = optionalValue else { return } // do something
如果
optionalValue
有值就赋值给realValue
,然后继续执行后面的代码,否则直接返回方法2
if let realValue = optionalValue { // do something }
如果
optionalValue
有值就赋值给realValue
,然后执行代码{}
中的代码,否则继续执行后面的代码
虽然看不懂,但还是大佬牛逼
var value: String!
这个value,不能说必须要有值,它的意思是使用的时候会强制拆包,nil的时候强制拆包会异常,只要没有使用,一直是nil都没有关系