kotlin 代码习惯1
让你的 Kotlin 代码远离 !!
简评:优雅的运用 Kotlin 的 null safety 特性,而不要简单的直接用 !!。
对于 Null 的检查是 Kotlin 的特点之一。强制你在编码过程中考虑变量是否可为 null,因此可以避免很多在 Java 中隐藏的 NullPointerException。
但是,当你用插件直接将 Java 代码转换为 Kotlin 时,你会发现有很多 !! 在里面。但其实 !! 意味着「有一个潜在未处理的 KotlinNullPointerException 在这里」。
这里就介绍 6 个避免 !! 的方法:
1. 用 val 而不是 var
在 Kotlin 中 val 代表只读,var 代表可变。建议尽可能多的使用 val。val 是线程安全的,并且不需要担心 null 的问题。只需要注意 val 在某些情况下也是可变的就行了。
可以看看这里:Mutable vals in Kotlin
2. 使用 lateinit
有些情况我们不能使用 val,比如,在 Android 中某些属性需要在 onCreate() 方法中初始化。对于这种情况,Kotlin 提供了 lateinit 关键字。
private lateinit var mAdapter: RecyclerAdapter<Transaction>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mAdapter = RecyclerAdapter(R.layout.item_transaction)
}
fun updateTransactions() {
mAdapter.notifyDataSetChanged()
}
要注意,访问未初始化的 lateinit 属性会导致 UninitializedPropertyAccessException。
并且 lateinit 不支持基础数据类型,比如 Int。对于基础数据类型,我们可以这样:
private var mNumber: Int by Delegates.notNull<Int>()
3. 使用 let 函数
下面是 Kotlin 代码常见的编译错误:
许多开发者都会选择 quick-fix:
private var mPhotoUrl: String? = null
fun uploadClicked() {
if (mPhotoUrl != null) {
uploadPhoto(mPhotoUrl!!)
}
}
但这里选择 let 函数是一个更优雅的解决方法:
private var mPhotoUrl: String? = null
fun uploadClicked() {
mPhotoUrl?.let { uploadPhoto(it) }
}
4. 创建全局函数来处理更复杂的情况
let 是一个对于 null 检查很好的替代品,但有时我们会遇到更复杂的情况。比如:
if (mUserName != null && mPhotoUrl != null) {
uploadPhoto(mUserName!!, mPhotoUrl!!)
}
你可以选择嵌套两个 let,但这样可读性并不好。这时你可以构建一个全局函数:
fun <T1, T2> ifNotNull(value1: T1?, value2: T2?, bothNotNull: (T1, T2) -> (Unit)) {
if (value1 != null && value2 != null) {
bothNotNull(value1, value2)
}
}
5. 使用 Elvis 运算符
Elvis 运算符在 Groovy 和 PHP 等语言中都存在。对于当值可能为 null 的情况特别方便:
fun getUserName(): String {
if (mUserName != null) {
return mUserName!!
} else {
return "Anonymous"
}
}
上面的代码就可以简化为:
fun getUserName(): String {
return mUserName ?: "Anonymous"
}
为什么叫 Elvis 呢?因为 ?: 很像猫王的发型:
6. 自定义崩溃信息
如果我们使用 !!,那么当这个变量为 null 时,只会简单的抛出一个 KotlinNullPointerException。这时我们可以用 requireNotNull 或 checkNotNull 来附带异常信息,方便我们调试。
uploadPhoto(requireNotNull(intent.getStringExtra("PHOTO_URL"), { "Activity parameter 'PHOTO_URL' is missing" }))
总而言之,绝大多数情况下你都不需要 !!,可以用上面提到的 6 个技巧来消除 !!。这样能让代码更安全、更容易 debug 并且更干净。
扩展阅读:
kotlin 代码习惯1的更多相关文章
- Typecho-Material主题不支持Kotlin代码高亮的解决方案
Typecho-Material主题不支持Kotlin代码高亮的解决方案 Overview 最近通过Typecho搭建了一个Blog,采用了 Material主题,其他的都挺好,也挺喜欢这个主题,但是 ...
- 快速书写常见的 Kotlin 代码 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- 怎样从Java转换到Kotlin代码:现在就开始使用Kotlin(KAD 29)
作者:Antonio Leiva 时间:Jul, 4, 2017 原文链接:https://antonioleiva.com/kotlin-from-java/ Kotlin最神奇特性之一是它能与Ja ...
- 注重代码习惯,Python零基础从这本书籍开始!
笨办法学 Python是Zed Shaw 编写的一本Python入门书籍.适合对计算机了解不多,没有学过编程,但对编程感兴趣的朋友学习使用.这本书以习题的方式引导读者一步一步学习编 程,从简单的打印一 ...
- 改变你代码习惯的ES6
最近读阮一峰老师的ES6标准入门,让我感觉到了ES6的强大之处,读书之余整理了一些笔记,因为边读边记录的,所以可能会比较杂乱. ECMAScript和Javascript的关系 1996年11月,Ja ...
- js-注释代码习惯
功能块代码 /** * xxxx */ 定义的函数或方法 /* xxxx */ 调用了某个函数或方法 // <--xxx
- 300行Kotlin代码实现的区块链
使用Kotlin实现的区块链基本逻辑! 源码地址 GitHub仓库 启动方式 启动参数添加 -Dserver.port=8080,启动不同的端口,模拟不同的节点. 假设目前启动了8080和8081两个 ...
- kotlin 代码格式
与java 不同,代码顺序影响编译过程. { var a:Int = 1; init(){ a++; } //var a:Int = 1; 写在 init 之后不可用. }
- 论好的代码习惯的养成/做一个优雅的coder
1.先说一下以前被滴滴大佬教育的事情: 以前写代码的时候,因为只需要取特定的几个字段,所以经常这么写 //Request $request for example $parameters = $req ...
随机推荐
- 500 Internal Privoxy Error
打开网站突然发现网站无法打开了,一脸懵逼,服务器重启也不行,明明能ping通,网上查的答案千奇百怪的 500 Internal Privoxy Error Privoxy encountered an ...
- 【接口测试】【SOAP】简单的接口测试学习
==================================================================================================== ...
- LeetCode 7 Reverse Integer & int
Reverse Integer 想用余10直接算,没想到 -123%10 是 7, 原因 -123-(-123//10*10) r=a-n*[a/n] 以上,r是余数,a是被除数,n是除数. 唯一不同 ...
- 使用EnterpriseLibrary插入Oracle CLOB数据
转自:http://www.programgo.com/article/20022195177/ http://blog.csdn.net/ddxkjddx/article/details ...
- ftp的安全问题
ftp漏洞http://www.4hou.com/technology/3507.html
- Jnlp
java web start解析jnlp文件,从网络宿主中,下载应用程序jar包,并运行. xxx.jnlp <?xml version="1.0" encoding=&qu ...
- SqlDataSource.FilterExpression Property
SqlDataSource.FilterExpression Property 定义 命名空间: System.Web.UI.WebControls Assembly: System.Web.dll ...
- JVM虚拟机宕机_java.lang.OutOfMemoryError: unable to create new native thread
原因:当前用户的系统最最大程序数数已达到最大值,使用ulimit -u可以看到是1024 解决办法:在当前用户下使用ulimit -u 65535 然后再执行jsp,一切ok 功能说明:控 ...
- Oracle创建表及管理表
转自:https://www.linuxidc.com/Linux/2018-05/152566.htm 1. Oracle表的创建及管理 创建表包括三个要素,表名,列名,数据类型.每个表都有对应 ...
- crontab 安装与配置
安装方法: yum -y install vixie-cron yum -y install crontabs 说明:vixie-cron 软件包是 cron 的主程序:crontabs 软件包是用来 ...