【Kotlin学习之旅】Kotlin的Elvis运算

Elvis运算是一个小技巧,其实就是if else 的简化写法。

一、示例程序

下面来一个示例对比代码,如下所示:

fun elvisTest() {
    var b: String? = "oyp"

    var len1 = if (b != null) b.length else -1
    //输出3
    println(len1)

    b = null

    var len2 = b?.length ?: -1
    // 输出 -1 
    println(len2)
}

在这里插入图片描述

len1 使用的是传统的if分支进行判断,当b不为null的时候返回b.length,否则返回-1

二、Elvis运算符

2.1 Elvis介绍

len2 使用的是 ?: 运算符,该运算符就是Elvis

它的含义是,如果 ?: 左边的表达式不为null,则返回左边表达式的值,否则返回?: 右边表达式的值。

由此可见, ?: 其实就是 if分支的简化写法。

2.2 Elvis分析

Elvis 操作符与安全调用符 ?. 配合使用时,一定要考虑到安全调用符前后是否为空,否则就会带来流程控制混乱的问题。对于刚才例子中的表达式:

val v = a?.b ?: c

因为 ?. 的优先级比 ?: 高,
首先计算 a?.b,按照安全调用符的规则,如果 a == null 则结果为 null,执行 c,
但如果 a.b == null,也会执行 c。

也就是说,它的执行逻辑是这样的:

var temp = if(a != null) a.b else null
val v = if(temp != null) temp else c

它等价于:

val v = if(a == null || a.b == null) c else a.b

所以我们上面介绍的例子,可以这样分析

 var len2 = b?.length ?: -1

等价于

 var len2 = if(b == null || b.length == null) -1 else b.length 

2.3 Elvis与return、throw表达式

由于Kotlin中return、throw都属于表达式,因此它们也可以在 ?: 运算符的右边。

与try语句是表达式一样,Kotlin的throw语句也是表达式。但是由于throw表达式的类型比较特殊,是Nothing类型,因此很少将throw语句赋值给其他变量。但是我们可以在Elvis表达式中使用throw表达式。

示例代码:

class User(var name: String? = null, var pass: String? = null)

fun main(args: Array<String>) {
    val user = User()
    // 在Elivs表达式中使用throw表达式
    // throw表达式表示程序程序出现异常,不会对变量赋值
    val th: String = user.name ?: throw NullPointerException("目标对象不能为null")
}

上面代码将user.name赋值给th变量,但是由于user.name是可空类型,因此程序对user.name使用了Elvis表达式进行判断;

  • 当user.name不为null的时候,将其赋值给th

  • 否则,使用throw表达式,throw表达式的类型是Nothing,用于标识程序无法“真正”得到该表达式的值。

因此,如果user.name为null,程序将出现异常,不会对th赋值,故可将th变量声明为String类型。

已标记关键词 清除标记
表情包
插入表情
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符 “速评一下”
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__0809 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值