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 ...
随机推荐
- nvm-windows安装
linux上的nvm太好用了,windows也出了,不过需要手动下载安装 地址: https://github.com/coreybutler/nvm-windows/releases 博主安装的是 ...
- JS自学总结的零散知识点
1.使用new关键字的时候后面不能接这种变量而是接一个结构constructor 例如由function引导的结构 而不是像如下这样 var car={ lunzi : 4}; 这个只是一个变量而不是 ...
- 报错,但不影响运行ERROR: JDWP Unable to get JNI 1.2 environment, jvm->GetEnv() return code = -2
参考:http://blog.csdn.net/zxl0016/article/details/7327125 eclipse 3.4+jdk1.6 编译正常通过,运行debug模式时报错 ERROR ...
- webDAV
wiki webDAV client - java https://github.com/lookfirst/sardine https://www.cnblogs.com/xgjblog/p/383 ...
- 【其他】SAS key 获得办法【转载】
小弟偶然得到了一个利用google得到SID的方法,经本人测试(9.4 64位)得到的SID可以用到2015年12月,从此之后再也不用改时间了.为了让更多的人看见,设定了回复可见.所有内容免费.路过的 ...
- Centos 7 下创建LVM流程
https://www.cnblogs.com/ssslinppp/p/5853312.html
- kettle实现sqlserver与mysql的连接并写入mysql
1.新建转换databasejoin 2.添加两个db连接 mysql的db连接kettlemysql以及sqlserver2008的db连接kettlesql 前提是在\data-integrati ...
- 1. apache如何启动
进入apache安装目录/bin/底下,用命令:./apachectl start 启动
- Centos代理上网设置
原文链接:http://m.blog.csdn.net/article/details?id=51851677 一.centos自带界面设置代理 1. 界面设置 squid默认代理端口3128. 2 ...
- MySQL把一个大表拆分多个表后,如何解决跨表查询效率问题
大表分表后每个表的结构相同,可以用sql的union 比如a,b表结构相同可以通过union来联接 select * from aunion allselect * from bwhere.... 其 ...
