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
}

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Kotlin 编程三分钟入门

    为什么使用Kotlin 项目一期在收尾了终于有时间折腾了,一个多月以来Kotlin从入门到现在,坚持用来开发的切身感受.因为语法与Java的区别挺大的一开始很想放弃,如果不是因为项目在使用,想必很少人会尝试这样一门小众语言,但是习惯后会发现这些年究竟浪费多少时间在写无用的Java代码了,Kotlin在兼容Java的基础上还能大大提升开发效率.Kotlin有许多特性但对于开发来说,快速适应和学习更为重要,很多时候我们都是在不明白其原因就开始使用的,正如我们不可能把Retrofit原理研究透才使用它

  • Android Kotlin的使用及简单实例

    Android Kotlin的使用及简单实例 写在前面的话,作为一个不熬夜的人,一觉醒来发现Kotlin成为了Android的官方语言,可谓是大喜过望.为了趁热打铁,我决定提前三天放出原定本周日Release的文章.希望能及时让大家了解一下Kotlin. 相信很多开发人员,尤其是Android开发者都会或多或少听说过Kotlin,当然如果没有听过或者不熟悉也没有关系.因为本篇文章以及博客后期的内容会涉及到很多关于Kotlin的知识分享. 在写这篇文章前的一个多月,Flipboard中国的Andr

  • Kotlin 开发环境详解及简单实例

    Hello Kotlin 在前段时间举办的Google I/O 2017上,Google宣布Kotlin成为Android官方的开发语言,这个最初发布于2011年的语言在短短的时间内就吸引了大量的开发者,而Google使得它进入了更多人的视线. Kotlin是一种开源的基于JVM的变成语言,由JetBeans公司开发(大概除了使用VS的.net开发者意外,都会或多或少听说或使用过IDEA吧),名字取自圣彼得堡附近的一个小岛(Koltin island). Kotlin是一种简单的语言,其主要目标

  • Kotlin 单例实例详解

    Kotlin 单例实例详解 单例的实现方法,可以通过同伴对象,或者 lazy. 示例: class Hello private constructor() { companion object { val instance = Hello() } } 通过 lazy 实现 class Hello private constructor() { private object Holder { val INSTANCE = Hello() } companion object { val insta

  • kotlin 官方学习教程之基础语法详解

    kotlin 官方学习教程之基础语法详解 Google 在今天的举行了 I/O 大会,大会主要主要展示内有容 Android O(Android 8.0)系统.Google Assistant 语音助手.Google 智能音箱.人工智能.机器学习.虚拟现实等.作为一个 Android 开发者,我关心的当然是 Android O(Android 8.0)系统了,那么关于 Android O 系统的一个重要消息是全面支持 Kotlin 编程语言,使得 Kotlin 成为了 Android 开发的官方

  • 详解Kotlin中的变量和方法

    详解Kotlin中的变量和方法 变量 Kotlin 有两个关键字定义变量:var 和 val, 变量的类型在后面. var 定义的是可变变量,变量可以被重复赋值.val 定义的是只读变量,相当于java的final变量. 变量的类型,如果可以根据赋值推测,可以省略. var name: String = "jason" name = "jame" val max = 10 常量 Java 定义常量用关键字 static final, Kotlin 没有static,

  • 使用Kotlin开发Android应用教程

    使用Kotlin开发Android应用 1.Kotlin介绍 [Kotlin](https://kotlinlang.org/) Kotlin是一门基于JVM的编程语言,它正成长为Android开发中用于替代Java语言的继承者.Java是世界上使用最多的编程语言之一,当其他编程语言为更加便于开发者使用而不断进化时,Java并没有像预期那样及时跟进. Java缺失的很多特性在最新的修订版中逐渐覆盖到了,但Android开发者暂时还没能够使用它们.这就使得类似Kotlin这样的语言有了用武之地了:

  • Kotlin 基础语法详细介绍

    Kotlin 基础语法详细介绍 基础语法 定义包名 包名的定义应当在源文件的头部 package my.demo import java.util.* // ... 文件路径和包名并不要求匹配,源文件可以被放置在文件系统任意位置 参考:包 定义函数 函数有两个Int类型参数和Int类型返回值: fun sum(a: Int, b: Int): Int { return a + b } 函数体中只有一个表达式并且作为函数的返回值: fun sum(a: Int, b: Int) = a + b 函

  • Kotlin基础教程之操作符与操作符重载

    Kotlin基础教程之操作符与操作符重载 Kotlin操作符的使用方法与其他语言差不多,最大的特点就在于infix function call(事实上infix function call并不是操作符的特性,而是函数的特性)和操作符重载. 可以看到在Kotlin中大部分的操作符都与一个函数相对应,之所以这样做,大概是为了进行操作符重载. Kotlin官方文档中强调"=赋值"操作在Kotlin中不是操作符,换句话说类似于x = y = z这样的连续赋值并不被允许(甚至赋值操作也不能和常规

  • Kotlin新手基础学习之Elvis操作符

    Kotlin简介 Kotlin是一门与Swift类似的静态类型JVM语言,由JetBrains设计开发并开源.与Java相比,Kotlin的语法更简洁.更具表达性,而且提供了更多的特性,比如,高阶函数.操作符重载.字符串模板.它与Java高度可互操作,可以同时用在一个项目中. kotlin 语言特性 kotlin中一切皆为对象 没有像java一般的基本数据类型,数值类型为:Int, Float, Double等 函数也是对象,可作为参数和返回值 自然就会有高阶函数和lambda 语法特性及规范

  • Kotlin学习教程之操作符重载详解

    前言 在 Kotlin 中,我们可以用 约定的操作符,代替 调用代码中以特定的命名定义的函数,来实现 与之对应的操作.例如在类中定义了一个名为 plus 的特殊方法,就可以使用加法运算符 + 代替 plus() 的方法调用.由于你无法修改已有的接口定义,因此一般可以通过 扩展函数 来为现有的类增添新的 约定方法,从而使得 操作符重载 这一语法糖适应任何现有的 Java 类. 算术运算符 我们就从最简单直接的例子 + 这一类算术运算符开始. data class Point(val x: Int,

  • Kotlin编程基础语法编码规范

    目录 前言 文章总览 1.Kotlin基本语法 1.1 函数声明 1.2 程序主入口 1.3 变量 1.4 条件表达式 1.5 when表达式 1.6 空值与空检测 1.7 区间使用 2.Kotlin编码规范 总结 前言 上一篇我们认识了Kotlin编程语言,也搭建好开发环境.本篇就进入Kotlin的基础语法介绍,与其他编程语言一样,Kotlin也有自己的一套编码规范. 文章总览 1.Kotlin基本语法 1.1 函数声明 使用关键字 fun 声明: fun sum(a: Int, b: Int

  • Kotlin编程基础数据类型示例详解

    目录 本文总览 1.数值类型 2.布尔型 3.字符串 3.1 字符串字面值 3.2 字符串模板 4.数组 4.1 普通数组 4.2 原⽣类型数组 5.类型检测和类型转换 5.1 智能转换 5.2 is 与 !is 操作符 5.3 转换操作符: as 与 as? 总结 本文总览 上一篇学习了Kotlin基础语法知识,本篇开始会深入探讨一下Kotlin各个基础语法点.首先来熟悉Kotlin的数据类型和类型转换版块. 1.数值类型 在Kotlin中提供了数值类型: 整数类型:Byte,Short,In

  • 值得收藏的asp.net基础学习笔记

    值得收藏的asp.net基础学习笔记,分享给大家. 1.概论 浏览器-服务器 B/S 浏览的 浏览器和服务器之间的交互,形成上网B/S模式 对于HTML传到服务器  交给服务器软件(IIS)  服务器软件直接读取静态页面代码,然后返回浏览器 对于ASPX传达服务器  交给服务器软件(IIS)   IIS发现自己处理不了aspx的文件,就去映射表根据后缀名里找到响应的处理程序(isapi,服务器扩展程序) 问题:IIS如何调用可扩展程序? 答:可扩展程序首先就是按照IIS提供的借口实现代码,所以I

  • Linux shell脚本基础学习详细介绍(完整版)第1/2页

    Linux shell脚本基础学习这里我们先来第一讲,介绍shell的语法基础,开头.注释.变量和 环境变量,向大家做一个基础的介绍,虽然不涉及具体东西,但是打好基础是以后学习轻松地前提. 1. Linux 脚本编写基础 ◆1.1 语法基本介绍1.1.1 开头程序必须以下面的行开始(必须方在文件的第一行):#!/bin/sh符号#!用来告诉系统它后面的参数是用来执行该文件的程序.在这个例子中我们使用/bin/sh来执行程序.当编辑好脚本时,如果要执行该脚本,还必须使其可执行.要使脚本可执行:编译

  • 零基础学习C/C++需要注意的地方

    谈及C/C++,功能强大.应用广泛,一旦掌握了后,若是再自学其他语言就显得轻而易举了.那为什么学C/C++的人少呢?很多人认为C/C++虽然博大精深,但也难学.其实就本人认为C/C++并非是"difficult(困难)"的,只要你能理清思路,掌握它的精髓,配合一套教材.那么学C/C++是一件非常容易且又其乐无穷的事.今天本人就与大家一起谈谈如何学习C/C++或者说学习C/C++应从哪几方面着手. 先来说说C语言. 1.入门后多看代码 在有一定基础以后一定要多看别人的代码.注意代码中的算

  • c++基础学习之如何区分引用和指针

    目录 前言 1.引用 1.1引用的概念 1.2引用的定义 1.3引用与const 1.4引用的使用场景 2.指针 2.1概念 2.2获取对象的地址 2.3利用指针访问对象 2.3空指针 2.4野指针 2.4.1概念: 2.4.2野指针的产生: 2.5各个指针类型的含义 2.6 void* 指针 2.7指向指针的指针 2.8指针与const 3.指针和引用的区别 总结 前言 对于我刚学c++的时候,最令我头疼的是引用和指针,老是区分不了它们,那么今天笔者将我的学习到的笔记总结出来,让大家少走一些坑

  • avaScript基础学习-基本的语法规则

    目录 一.运算符 二.分支语句 三.循环语句 四.异常的捕获与处理 五.js中的this关键字 六.let与const定义变量使用规则 七.js中的void链接 八.异步编程setTimeout 九.函数闭包 一.运算符 js中的+-*/运算与c语言较为相似,简写方式也类似 ++.--.+=.%=等运算规则也相同 在js中===代表绝对等于(值与类型都相同才算相同) !==(不绝对等于)值和类型有一个不相同或者都不相同为真 js中还支持三目运算符 a>b?'a大于b':'b大于a' 二.分支语句

  • Python基础学习列表+元组+字典+集合

    目录 一.列表 二.元组 三.字典 四.集合 五.总节 前言: 这一章的知识紧接上一章,零基础的小伙伴可以从上一章学起来.当然,你也可以收藏起来慢慢学习,学习是不可操之过急的啦… 一.列表 print("-------------创建列表-------------"); list1 = ['JAVA', 'Hello', 'Python', 'VS', 1, 2, 3] print(list1) list2 = list('Python') print(list2) list3 = [

随机推荐