优雅的运用 Kotlin 的 null safety 特性,而不要简单的直接用 !!双感叹号

对于 Null 的检查是 Kotlin 的特色之一。强制你在编码过程当中考虑变量是否可为 null,所以能够避免不少在 Java 中隐藏的 NullPointerException。android

可是,当你用插件直接将 Java 代码转换为 Kotlin 时,你会发现有不少 !! 在里面。但其实 !! 意味着「有一个潜在未处理的 KotlinNullPointerException 在这里」。安全

这里就介绍 6 个避免 !! 的方法:ide

1. 用 val 而不是 var

在 Kotlin 中 val 表明只读,var 表明可变。建议尽量多的使用 val。val 是线程安全的,而且不须要担忧 null 的问题。只须要注意 val 在某些状况下也是可变的就好了。函数

能够看看这里:Mutable vals in Kotlin

2. 使用 lateinit

有些状况咱们不能使用 val,好比,在 Android 中某些属性须要在 onCreate() 方法中初始化。对于这种状况,Kotlin 提供了 lateinit 关键字。ui

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。对于基础数据类型,咱们能够这样:spa

private var mNumber: Int by Delegates.notNull<Int>() 

3. 使用 let 函数

下面是 Kotlin 代码常见的编译错误:.net

 

 

 

 

许多开发者都会选择 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 而且更干净。

原文:How to remove all !! from your Kotlin code
相关文章
相关标签/搜索