美文网首页
OC vs Swift -- Optional

OC vs Swift -- Optional

作者: JellyL | 来源:发表于2017-03-27 23:43 被阅读207次

    Why Optional#

    引入optional可以解决两个问题,

    1. 解决潜在crash问题
    [dict setObject: objc forKey: @“someKey"];
    

    比如OC中像集合dict的someKey设置值为objc, 当objc为nil时,程序运行到这句代码时会crash,利用 optional 的机制更严格的类型检查,使得在编译时可以发现更多问题,把这种潜在的错误及时的排除掉了;

    1. 解决空类型不详的问题,“无”和“空”划分得更清晰,表述更明确, 让代码可读性更高。

    定义#

    Optional定义

    OC和Swift中通过不同的修饰符来表示optional变量,由于swift有语法糖的支持,所以OC相对于Swift来说语法上略显得啰嗦了一些。但是在OC中为了防止写一大堆 nonnull,Foundation 还提供了一对宏,包在里面的对象默认加 nonnull 修饰符,只需要把 nullable 的指出来就行。

    #import "Ship.h"
    
    NS_ASSUME_NONNULL_BEGIN
    @interface ShipList : NSObject
    
    - (nullable Ship*)shipWithName: (NSString *)name;
    - (NSInteger)indexOfShip: (Ship *)ship;
    
    @property (copy, nullable) NSString *name;
    @property (copy, readonly) NSArray *allShips;
    
    @end
    NS_ASSUME_NONNULL_END
    

    其实OC中并没有真正支持optional, 只是编译器帮忙做了检查,会对错误提出警告,但是程序依然可以通过编译,在运行时会crash。


    OC-Optional.png

    而相同的代码用Swift实现,编译器在编译过程中就会报错。


    Swift-Optional-Check.png

    Swift中的Optional是由ENUM + 范型定义的一个数据类型; Optional.none 是空的字面量,Optional.some(Wrapped) 存储了一个包裹的值。引入Optional封装nil,nil有类型后,才能融入强类型语言范畴。


    Optional.png

    这个被包裹的值就好像礼物盒子里的礼物一样,你只有把盒子打开才知道里面的东西到底是什么。

    struct Gift {
        let sender: String = "June"
        let name: String = "💄"
    }
    
    func whatIsTheGift(giftBox: Gift?) {
        if let gift = giftBox {
            print("the giftis \(gift.name)")
        } else {
            print("there is no gift")
        }
    }
    
    var 🎁: Gift?
    whatIsTheGift(🎁)
    // there is no gift
    
    🎁 = Gift()
    whatIsTheGift(🎁)
    // the gift is 💄
    

    而打开礼物这个过程我们通常称为unwrapp(解包或者拆包),Swift有以下几种方式进行解包:

    * !  (直接解包,快速,短小精悍, 但如果沒值会直接crash,使用的时候一定要保证optional变量有值)
    * if / switch (可以避免沒有值还硬拆的狀況,也可以处理沒有值的情况)
    * if let / guard let  (可以从第三方拆完直接拿到值,不用自已拆)
    * ??  (空合运算符,当optional变量为 nil 时,直接提供符合逻辑的初始值,但是可能引起难以定位到错误原因的问题,慎用)
    

    举个🌰,一个optional变量 name,当值为June时,5种方式进行解包都可以,打印结果一致。

    Optional-unwrap-example-one
    但是当optional变量 name值为nil时, 直接解包的方式会crash掉。而空合运算符解包的方式打印结果与其他三种并不相同。
    optional-unwrapp-exaple-two

    所以总体来说应该首选if let / guard let, 最不建议直接使用!,而?? 根据使用场景来选择,慎用。

    相关文章

      网友评论

          本文标题:OC vs Swift -- Optional

          本文链接:https://www.haomeiwen.com/subject/ziedottx.html