Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Kotlin之Elvis 操作符

Kotlin之Elvis 操作符

作者头像
xiangzhihong
发布于 2018-02-06 11:50:17
发布于 2018-02-06 11:50:17
1.3K00
代码可运行
举报
文章被收录于专栏:向治洪向治洪
运行总次数:0
代码可运行

Elvis 操作符的优先级

首先要注意到,Elvis 操作符的优先级是比较低的,特别是比加减乘除的运算符低,混合运算时一定要记得加上括号。比如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fun <T> Iterable<T>.contentHashCode(): Int {
    return fold(1) {
        hash, element ->
        hash * 31 + (element?.hashCode() ?: 0)
    }
}

这里如果不用括号将 element?.hashCode() ?: 0 括起来,编译器就会认为这句表达式是 (hash * 31 + element?.hashCode()) ?: 0,出现编译错误。

与 ?. 配合使用时的问题

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val v = a?.b ?: c

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

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var temp = if(a != null) a.b else null
val v = if(temp != null) temp else c

它等价于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val v = if(a == null || a.b == null) c else a.b

实际使用时一定要注意 ?. 前后是否都可能为 null。

?: 与流程控制语句的搭配使用

我发了一个 Kotlin 写的前序遍历二叉树的 Gist,地址在这里:PreOrderTraversing.kt,整个项目:DataStructureLearning-Kotlin 非递归遍历二叉树的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
private fun preOrderLoop(
    root: Node? = this.root,
    list: MutableList<Int> = mutableListOf()
): List<Int> {
    val stack = ArrayDeque<Node>()
    stack.push(root ?: return list)

    while (stack.isNotEmpty()) {
        val nodeNow = stack.pop()!!
        list += nodeNow.value
        nodeNow.right?.let { stack.push(it) }
        nodeNow.left?.let { stack.push(it) }
    }
    return list
}

第二句很有意思。ArrayDeque 不能容纳 null,一旦插入 null 就会抛出 NPE,而我们的函数要求 root 为 null 时返回一个空的 List,所以这里 push() 的参数写成 root ?: return list,这句代码的逻辑如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
if(root == null) return list
stack.push(root)

此外,Elvis 还可以配合 break 和 continue 来控制循环流程。

改良 Elvis

Elvis 操作符很方便,但只能连接表达式,我们可以写一个扩展函数来作为加强版的 Elvis 操作符。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
inline infix fun <T : Any> T?.ifNull(block: (T?) -> T): T {
    if (this == null) {
        return block(this)
    }
    return this
}

使用方式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val file = java.io.File("C:\\FakeFile")
val parent = file.parent ifNull {
    // do something here
}    
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017-12-02 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
第2章 Kotlin 语法基础第2章 Kotlin 语法基础
人与人之间通过语言来交流沟通,互相协作。人与计算机之间怎样“交流沟通”呢?答案是编程语言。一门语言有词、短语、句子、文章等,对应到编程语言中就是关键字、标识符、表达式、源代码文件等。通常一门编程语言的基本构成如下图所示
一个会写诗的程序员
2018/08/17
2.7K0
第2章 Kotlin 语法基础第2章 Kotlin 语法基础
Kotlin鱿鱼游戏大奖赛
提示:在IDE里面,lint会提示,Unused return value of a function with lambda expression body
用户1907613
2021/11/19
6390
Kotlin 轻量级Android开发
它由Jetbrains创建,而Jetbrains则是诸多强大的工具(如知名的Java IDE IntelliJ IDEA)背后的公司。Kotlin是一门非常简单的语言,其主要目标之一就是提供强大语言的同时又保持简单且精简的语法。
Yif
2019/12/26
9740
Kotlin之基本语法
在今年Google IO大会上Google已经明确kotlin作为为Android第一官方语言的地位。我相信Google的决意,就像当初毫不犹豫的抛弃eclipse转向as,kotlin已经是不可避免的大势所趋了。再加上Kotlin与java代码完全兼容,所以从Java转向Kotlin是一件很容易的事情。Kotlin语法简单,它融合了当前多种语言的优势,可以是一门明星语言。 下面就Kotlin的一些基本语法做一个讲解。 包 一个源文件往往以包声明开始:源文件的所有内容(比如类和函数)都被包声明并包括。 pa
xiangzhihong
2018/01/26
1.1K0
Kotlin安卓开发学习(3)
在Java中,数据类占据着重要的角色,其通常需要重写包括equals(),hashCode(),toString()几个方法。
摸鱼的G
2023/02/22
5760
【Kotlin 协程】Flow 操作符 ② ( 末端操作符 | collect 操作符 | reduce 操作符 | single 操作符 | first 操作符 | toList 操作符 )
末端操作符 指的是 在 Flow 流最末端 调用 挂起函数 收集元素 的操作符 , 最常见的 末端操作符 就是 collect 操作符 ;
韩曙亮
2023/03/30
1.1K0
【Kotlin 协程】Flow 操作符 ② ( 末端操作符 | collect 操作符 | reduce 操作符 | single 操作符 | first 操作符 | toList 操作符 )
算法细节系列(25):加减乘除
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014688145/article/details/72782815
用户1147447
2019/05/26
5250
操作符详解(2)
C语言的整型算术运算总是至少以缺省(默认)整型类型的精度来进行的;为了获得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升。
waves浪游
2024/01/22
1450
操作符详解(2)
【翻译】Kotlin致简代码之路
2017-06-30 by Liuqingwen | Tags: Kotlin 翻译 | Hits
IT自学不成才
2019/01/07
1.5K0
Data Structure_数组_栈_队列_链表_霍夫曼数组栈队列链表哈夫曼
这就表示一个数组,这个数组有八个元素存放。对于元素的获取,主要就是通过下标获取,所以索引对于数组是很重要的,这个索引可以是有意义的,也可以是没有意义的。比如array【2】这个数组,可以是仅仅代表下标,也可以是有一个意义在里面,代表学号分数等等。Java里面有存在静态数组,直接int[]赋值,但是这种方法是不能动态初始化的,我们二次封装一个:
西红柿炒鸡蛋
2018/12/13
7900
《Kotlin极简教程》第3章 Kotlin语言基础第3章 Kotlin语言基础《Kotlin极简教程》正式上架:参考资料
学习任何东西,都是一个由表及里的过程。学习一门编程语言也一样。对于一门编程语言来说,“表” 就是基本词汇(关键字、标识符等)、句子(表达式)和语法。
一个会写诗的程序员
2018/08/17
1.8K0
《Kotlin 程序设计》第四章 Kotlin 语法基础
Kotlin 可以省略变量定义的类型声明,但是在定义参数列表和定义返回值类型时则必须明确指定类型(这个类型推断Kotlin居然没做,这地方用起来比Scala,Groovy要繁琐点)。
一个会写诗的程序员
2018/08/17
1.5K0
抱歉!不要用Java的语法思维来写Kotlin
如果你是像我一样是一名 优秀的Java开发者 ^_^,而且已经想用kotlin来实现你的程序,那么,抱歉!不要用Java的语法思维来写Kotlin,不要让kotlin的优雅埋没。如果你没有Java开发经验,下面的内容也对你会有帮助。。。
全科
2018/08/15
3.1K0
Kotlin语法基础之运算符
运算符 计算机程序中最小的程序单位成为表达式,每个表达式都可以由两部分组成,即操作数和运算符。操作数可以是变量、常量、类、数组、方法等,甚至是其他表达式。而运算符则用于支出表达式中单个或者多个操作数参与运算的规则,表达式通过运算之后产生的值依赖于表达式中包含的运算符的优先级和结核性。Kotlin语言包含了Java语言中的所有运算符的特性,并结合C语言的优点,增加自定义运算符的逻辑。这些运算符之中,主要包括有:算数运算符、区间运算符、逻辑运算符、关系运算符、赋值运算符、自增自减运算符等。 根据操作数的数量来划
xiangzhihong
2018/02/06
3K0
Kotlin语法基础之运算符
【Kotlin】Kotlin 基础语法指南
在 Kotlin 中,变量使用 var 声明,而常量则使用 val 声明。val 表示的变量在初始化后不能再修改,而 var 则可以在之后重新赋值。
人不走空
2024/07/13
1670
Kotlin入门教程,快使用Kotlin吧
数组用Array类实现,和Java不同的地方在于,Array类有一个size属性表示数组长度,还有get和set方法,但是也可以使用array[position]的方式获取
用户2802329
2018/08/07
1.1K0
Kotlin入门教程,快使用Kotlin吧
Kotlin学习笔记
在 Java 中有 switch 语句,在 Kotlin 中使用 when 来代替 switch
用户9854323
2022/06/25
1.9K0
Kotlin学习笔记
给 Java 开发者的 Kotlin 快速上手教程(Kotlin for Java Developers)v0.1
1995年,当年如日中天的Sun公司发布了Java语言,引起了巨大的轰动,与当时主流的C语言和Basic语言比起来,Java语言简单、面向对象、稳定、与平台无关、解释型、多线程、动态等特点,就像是打开了一个新的世界,一时间风靡全球,云集者众,微软为了模仿Java搞出C#语言,Netscape为了赶时髦硬塞出一个JavaScript语言,IBM则捏着鼻子做了Java IDE Eclipse(日蚀,呵呵)。直到现在,Java在编程世界里还占据着举足轻重的地位,Andy Rubin在开发Android系统时,也很自然地采用了Java和C++(C++负责NDK开发)作为开发语言。
一个会写诗的程序员
2018/12/07
1.1K0
给 Java 开发者的 Kotlin 快速上手教程(Kotlin for Java Developers)v0.1
Kotlin | 6.Kotlin 的类型系统
本章内容包括: 处理 null 的可空类型和语法 基本数据类型和它们对应的Java类型 Kotlin 的集合,以及它们和Java的关系 6.1 可空性 /**-----------
Jingbin
2021/03/02
2.4K0
Kotlin 如何优雅地使用 Scope Functions
作用域函数:它是 Kotlin 标准库的函数,其唯一目的是在对象的上下文中执行代码块。 当您在提供了 lambda 表达式的对象上调用此类函数时,它会形成一个临时范围。 在此范围内,您可以在不使用其名称的情况下访问该对象。
fengzhizi715
2019/07/15
9660
相关推荐
第2章 Kotlin 语法基础第2章 Kotlin 语法基础
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验