5. swift & kotlin Optional 的用途

用了 optional 是不是不会为空呢?

这个显然不用问的,肯定是能够为空的,难道程序还能拦住人不成?
比如这样的代码

func jump(str : String){}
jump(nil!) // 我这样写你能奈我何?

那么这个东西的用处是什么?

声明不为空

为了明确各自的边界
比如 Java 的一个方法

void jump(String name){    
    if(name.lenght != 0){
        // do
    }
}

如果外部传入空值怎么办?
第一波尝试,增加 NouNull 注解

void jump(@NouNull String name){    
    if(name.lenght != 0){
        // do
    }
}

但是注解只是编译提醒,人家不看编译提醒还是传了空怎么办?
那就第二波修改,null 检查

void jump(@NouNull String name){    
    if (name == null){
        throw new IllegalArgumentException("参数不能为空");
    }
    if (name.lenght != 0){
        // do
    }
}

第二波修改明显就能够防止问题的,但是如果让你每个方法都这样写一遍,是不是感觉很累?

kotlin 简化了这种写法

fun jump(name: String) {
    if(name.isNotEmpty()){
       //do  
    }
}

当你尝试这样调用的时候 jump(null) 会编译直接报错,因为这里声明的不是可选类型,不能为空。
如果你这样写 jump(null!!)那就会运行时候报错,自动检查空

swift 也是一样

func jump(name: String) {
    if ( name.lenght != 0){
       //do  
    }
}

减少判空的噪音

同样的java代码,要判空需要这样写

void jump(String name){    
    if(name != null && name.lenght != 0){
        // do
    }
}

但是 kotlin 只需要这样

fun jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

swift 也是这样

func jump(name: String?){    
    if(name?.lenght != 0){
        // do
    }
}

其实我觉得最方便的时候是有个类需要接受一个 callback
这个 callback 是可以为空的,然后你就需要每个使用的地方都加个空判断,就比如下面这样的代码

class PushManager{
    private PushCallback pushCallback;
    
    private void onPush(){
        if(pushCallback != null){
            pushCallback.onGetPushData();
        }
    }
}

但是如果换成 kotlin 编写的话就非常愉悦了

class PushManager{
    private var pushCallback : PushCallback?;
    
    private onPush() {
        pushCallback?.onGetPushData();
    }
}

简直和不用写判空一样,这样减少了很多代码噪音,让开发人员更加专注于编写代码本身