Kotlin新手基础学习之Elvis操作符
kotlin简介
kotlin是一门与swift类似的静态类型jvm语言,由jetbrains设计开发并开源。与java相比,kotlin的语法更简洁、更具表达性,而且提供了更多的特性,比如,高阶函数、操作符重载、字符串模板。它与java高度可互操作,可以同时用在一个项目中。
kotlin 语言特性
kotlin中一切皆为对象
- 没有像java一般的基本数据类型,数值类型为:int, float, double等
- 函数也是对象,可作为参数和返回值
- 自然就会有高阶函数和lambda
语法特性及规范
- 语句结尾不用分号
- 使用驼峰命名,尽量避免下划线
- public函数应当有说明文档
- lambda中花括号内前后都应该有空格
elvis 操作符的优先级
首先要注意到,elvis 操作符的优先级是比较低的,特别是比加减乘除的运算符低,混合运算时一定要记得加上括号。比如:
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 操作符与安全调用符 ?. 配合使用时,一定要考虑到安全调用符前后是否为空,否则就会带来流程控制混乱的问题。对于任何一个下列的表达式:
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
实际使用时一定要注意 ?. 前后是否都可能为 null。
?: 与流程控制语句的搭配使用
我发了一个 kotlin 写的前序遍历二叉树的 gist,地址在这里:preordertraversing.kt,整个项目:datastructurelearning-kotlin
非递归遍历二叉树的代码如下:
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
,这句代码的逻辑如下:
if(root == null) return list stack.push(root)
此外,elvis 还可以配合 break 和 continue 来控制循环流程。
改良 elvis
elvis 操作符很方便,但只能连接表达式,我们可以写一个扩展函数来作为加强版的 elvis 操作符。
inline infix fun <t : any> t?.ifnull(block: (t?) -> t): t { if (this == null) { return block(this) } return this }
使用方式:
val file = java.io.file("c:\\fakefile") val parent = file.parent ifnull { // do something here }
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对的支持。