通常咱们在一下两种状况下会遇到!和?的使用
1.声明变量时segmentfault
var number :Int? var str : String!
2.在对变量操做时spa
number?.hashValue str!.hashValue
因为这两种状况的意义不一样,因此分开进行解释:code
1.声明变量时
在声明一个变量时若是不手动初始化,Swift不会自动初始化该变量为一个默认值的。图片
var a : String var b = a //error:由于没有初始化a,a没有值
可是对于Optional的变量则不一样,Optional的变量在声明时若是不初始化,Swift会自动将该变量初始化为nil。声明变量时在类型后添加?或者!就是告诉编译器这个一个Optional的变量,若是没有初始化,你就将其初始化为nil编译器
var a : String? //a 为nil var b : String! //b 为nil var a_test = a //a_test为nil var b_test = b //b_test为nil
可是这二者之间仍是有一些区别的,介绍后面以后再讲。
Optional事实上是一个枚举类型,从下图能够看出,Optional包含None和Some两种类型,而nil就是Optional.None,非nil就是Optional.some。若是Optional变量在声明时不初始化,Swift会调用init()来初始化变量为nil,而用非nil的值初始化变量时,会经过Some(T)把该原始值包装,因此在以后使用的时候咱们须要经过解包取出原始值才能使用。hash
2.对变量进行操做时it
var arrayCount = dataList?.count
这时问号的意思相似于isResponseToSelector,即若是变量是nil,则不能响应后面的方法,因此会直接返回nil。若是变量非nil,就会拆Some(T)的包,取出原始值执行后面的操做。io
var arrayCount = dataList!.count
这里的叹号和以前的问号则不一样,这里表示我肯定dataList必定是非nil的,因此直接拆包取出原始值进行处理。所以此处若是不当心让dataList为nil,程序就会crash掉。编译
回到上面声明时?和!区别的问题上去
声明变量时的?只是单纯的告诉Swift这是Optional的,若是没有初始化就默认为nil,而经过!声明,则以后对该变量操做的时候都会隐式的在操做前添加一个!。class
总结