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 ...
随机推荐
- 【Jmeter自学】Linux环境下Jmeter运行
==================================================================================================== ...
- day5--装饰器函数的信息打印,迭代器,生成器,列表推导式,内置函数
本文档主要内容: 一 装饰器函数的信息打印 二 迭代器 三 生成器 四 生成器表达式和列表推导式 五 内置函数 一 装饰器函数的信息打印 一个函数一旦被装饰器给装饰后,这个函数的信息使用原来的命令打印 ...
- win7 安装英文语言包
因为某些英文程序字符显示不全,所以考虑把 win7 改为英文语言.直接下载英文语言包安装不成功,经过多次尝试和百度终于找到合适的办法. 下载 Vistalizator.exe, windows6.1- ...
- 学习excel的使用技巧一空格替换为0
问题1 把excel表格中的空格 填充为0 方法1 选中CDE列 CRTL+F 查找空 替换为0 方法2 选中CDE列 CRTL+G 打开定位 点击条件定位 选择空值 点击确定 然后在 ...
- 5.分析mitmproxy的优势及工具mitmdump的使用(参照书籍)
mitmproxy优势:功能和charles.fiddler相似,强大之处在于它的工具 mitmdump 可以直接对接python 对请求做处理. mitmdump使用 : 1.mitmdump是mi ...
- py库: jieba (中文词频统计) 、collections (字频统计)、WordCloud (词云)
先来个最简单的: # 查找列表中出现次数最多的值 ls = [1, 2, 3, 4, 5, 6, 1, 2, 1, 2, 1, 1] ls = ["呵呵", "呵呵&qu ...
- 字符串流stringReader
String info ="good good study day day up";StringReader stringReader = new StringReader(inf ...
- Django - session 会话跟踪技术
1.session简介 |session 英 /'seʃ(ə)n/ 美 /'sɛʃən/ 基于cookies开发,将值存到服务端 写session 读session Session是服务器端技术,利用 ...
- java 使用jsoup处理html字符
依赖的jar <dependency> <groupId>org.jsoup</groupId> <artifactId>jsoup</artif ...
- SQL Server CLR 使用 C# 自定义存储过程和触发器
资源来源:https://www.cnblogs.com/Brambling/p/8016060.html SQL Server CLR 使用 C# 自定义存储过程和触发器 这一篇博客接着上一篇博 ...