美文网首页
用 Kotlin 写 Android 8—可空性

用 Kotlin 写 Android 8—可空性

作者: jkwen | 来源:发表于2021-05-14 12:20 被阅读0次

Kotlin 将空指针问题由运行时提前到了编译期,从而减少了错误的出现。对类型这一概念的理解,Kotlin 显的比 Java 更纯粹,声明什么样的类型就对应着能做什么样的操作,而 Java 要额外考虑 null 的情况。具体 Kotlin 的可控性体现有以下几点。

?

? 加在类型后面表示可空,不加 ? 则表示非空。

?.

对于可空类型用 ?. 可以安全引用,其实 ?. 操作就是一次 null 判断和方法的调用的结合。

?:

但是如果可空变量真的是 null,那么即使 ?. 引用,结果依然是 null,这时可以用 ?: 来做为 null 时的处理。?: 表示当左边结果为 null 时,可以用右边的值表示,例如,

user?.name ?: "" //表示如果 user 为 null,那么获取用户名称的结果就为空串

一种更简便的处理就是 ?: 后面接 return 或者抛异常,从而可以终结向下的操作。

let{}

在实际开发时,有一种常见的操作时方法入参要求非空,而我们能提供的是可空的,之前我的转换方式是利用 ?: 在左边为 null 时右边返回 "" 或者特殊值。不过 Kotlin 提供了更优雅的方式,即 let 函数,同时配合 ?. 使用是最佳的。

user?.let{ createCounter(it) } // 这个就表示只有当 user 不为 null 时才会调用 createCounter 方法,it 是 lambda 表达式。

let 这个函数同样可以被表达式调用,这样就省去了临时变量的创建。但考虑到 let 函数已经很简化了,所以不要多个可空变量嵌套着使用,否则代码的可读性就差了很多,建议先做非空判断,在最后再用 let 函数。

!!

如果明确知道变量值就是不为空的,那么可以用非空断言。可如果一旦没考虑到位出现了空值,那么还是会报空指针异常,并且这个异常只能提示在哪一行代码,并不能指明谁调用引起的,所以我觉得能不用还是不用,或者尽量不要在核心位置或复杂的地方使用。

as?

同 ?. 一样,在类型转换是也可以进行安全转换,再搭配上 ?: 也可以很优雅。

lateinit

同样从实际场景出发,有些变量声明后没法立马进行初始化,它的值有可能要等网络请求回调或者通过其他值的计算得到,那么此时这种变量可由 lateinit 修饰,并且只能用 var 修时,不能用 val。同时还要注意调用时机,不能早于它的初始化就访问调用。

可空型扩展和泛型

为可空类型定义扩展函数时,一定要做的操作就是判断是否为 null,否则扩展函数就会在空值时出现异常。
当我们定义泛型时,默认是可空的,只有为泛型 T 确定上界,才能明确知道 T 是可空类型还是非空类型。

Kotlin 与 Java 的混编

因为 Kotlin 与 Java 的类型定义不同,所以在混编衔接时一定要小心可控性问题,为了确保程序的稳定性,再怎么判断非空我觉得都不为过,虽说 Java 的 @Nullable 和 @NotNull 可以转化为 Kotlin 的可空和非空,但那其实并不可靠,所以还的靠我们自己留意。

相关文章

网友评论

      本文标题:用 Kotlin 写 Android 8—可空性

      本文链接:https://www.haomeiwen.com/subject/corodltx.html