美文网首页
[Kotlin] Elvis表达式中的神坑

[Kotlin] Elvis表达式中的神坑

作者: Cocoonshu | 来源:发表于2020-08-21 10:44 被阅读0次

    在Kotlin中大家会用{} ?: {}来代替? {} : {}表达式使用,?:被称为Kotlin的Elvis表达式。

    问题

    读下面这段代码,大家看看它的打印值会是什么?

    class Pack {
    
        var text: String? = ""
    
        fun foo() {
            val result: String? = text?.run {
                println("block 1")
                null
            } ?: run {
                println("block  2")
                "B"
            }
            println("result = '$result'")
        }
    
    }
    

    输出结果:

    block 1
    block 2
    result = 'B'

    是不是和你意想中的结果不一样?

    分析

    我们来看看代码的执行过程:

    • STEP1text不为null时,?.判断通过,执行“block 1”所在的run代码块
    • STEP2 当“block 1”所在的run代码块返回null时,text?.run {}被看做一个整体亦为```null``
    • STEP3 执行null ?: run {}的判断,?:之前为null,跟textnull是同一个概念,因此?:判断通过,执行“block 2”所在的run代码块

    解决方案

    这个问题的重点在于val result的接受类型是String?而不是String
    当代码修改为如下时,这个问题就可以避免:

    class Pack {
    
        companion object val EMPTY_STRING: String = ""
     
        var text: String? = ""
    
        fun foo() {
            val result: String = text?.run {
                println("block 1")
                EMPTY_STRING
            } ?: run {
                println("block  2")
                "B"
            }
            println("result = '$result'")
        }
    
    }
    

    总结

    • 当表达式接收值为val result: String时,此代码块是一个if...else...表达式
    • 当表达式接收值为val result: String?时,此代码块是一个switch...case表达式

    相关文章

      网友评论

          本文标题:[Kotlin] Elvis表达式中的神坑

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