可选项
var a:Int 这个语句不会报错,但是实际使用的时候会报错,因为a在没初始化的情况下是nil,swift在非可选项的情况下是不允许有nil的,但是加个?变成var a:Int?,虽然还是会报警告,但至少可以使用了,打印的结果就是nil,这个就是可选项,可以为空,但如果可选项处理nil的情况是会报警告的
强制解包
当用了可选项后,生成的变量就是可选项类型,哪怕之前是Int, 这时候也会变成Optional(10)这种形式,而不能拿来直接使用,用的话也简单,加个!强制解包,例如
否则就会报错,但如果是nil,强制解包就会报这个错误Fatal error: Unexpectedly found nil while unwrapping an Optional value
所以使用可选项必须要先判断是否为空
这样,但是明显swift有更好的处理方式,并不用这么写,虽然这样也可以,比如可选项绑定
可选项绑定
可选项绑定就是获取可选项的值,如果获取不到则到else,和判断是否为空,是一个原理
这个就叫可选项绑定了,这样操作之后v直接就是Int而不是一个可选项,其实原理和判断是否为空解包没有什么区别,但可选项绑定不止是这里可以用
比如在枚举的生成也是可以使用可选项的对于这种原始值的枚举,可以试图用原始值创建一个枚举,但不一定成功所以会返回一个可选项,比如这个代码里面的就是south,如果5的话就是并不匹配任何方向,基本语法,没什么好赘述的
也可以多条件判断
如果之前的解包还可以用其它方式简单的替代的话,这个多重判断不用可选项绑定就要多不少代码了,这只是举个例子,比如拿实战来说,从网络返回的值,两个值需要比较才能判断类型的复杂业务,用这个就要简单的多了,并且在数组遍历也是用的上的
比如这个数组遍历,这种写法的意义就是遇到无法转为整数的就结束,后面的条件实际没生效,多个条件中间放,结果sum是46,因为遇到ABC就停止了
空合并运算符
空合并运算符是针对可选项的类似三目运算符形式的运算符
具体符号和使用方式如下
空合并运算符,就是两个?
func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T) rethrows -> T func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?) rethrows -> T?
并且图中三个运算符都是空合并运算符,但实际是两种不同的函数声明,比如第一第二个是第一种函数,第三个是第二种函数,从函数声明就能看出来,左边的参数必须是个可选项,区别在右边,可以是,可以不是,右边是可选项返回的就必然是可选项,否则则返回一个非可选项,一般来说就是可以直接使用的属性,
总结下,返回什么由右边决定,右边是可选项就返回可选项,否则就返回非可选项,而返回的值由左边决定,左边有值就直接返回,没有就返回右边的值,两边都没值就返回nil
多个空合并运算符
字面意思就是多个运算符一起用,print(a ?? b ?? 4)这个返回的是1,没什么问题,第二个因为最右边是可选项的问题,所以返回的是可选项的1,但是会报警告,不建议这么做,实际可以
??和if一起用,这个没什么好说,因为返回的是可选项,所以肯定可以用可选项绑定
guard语句
guard语句和if很像,区别在于if是满足条件就执行,guard则是不满足则执行,满足则跳过,我第一个想到的就是登陆注册,过滤一堆不合法的字符串
实际开发要过滤的东西要更多,这里就是一个模拟,初始化一个账号密码,如果没有从输入框获取到值,则会自动过滤,如果获取到了则会通过,是一个实战比较常见的操作
隐式解包的可选项
隐式解包的可选项和可选项的区别在于一个是?一个是!
声明大约就是这样
实际使用来说,隐式可选项直接就会解包,不用加!来强制解包,但有一个问题你敢给它个nil它就敢崩溃给你看,不是很建议这种写法
字符串插值
一般实际开发来说print都是打印debug信息,说句通俗点的,打印出来的东西自己能看懂就行了,所以使用插值,还是直接写后面区别不大,自己能看懂就好,毕竟用户是看不到的,简单了解就好
多重可选项
多重可选项也是??两个问号,不过区别在于,let a :Int?? 多重可选项是直接声明那用,运算符是在运算的时候用,
多重可选项是包含可选项的可选项,正好截个图
如图所示大约能看懂多重可选项的结构图了
但是在都是nil的情况下还是有所区别的
想看多重可选项有个lldb指令 fr v -R 可选项名称 ,就可以查看可选项的具体结构了,和图上没啥区别