Kotlin技术分享:空安全


  一、空安全

  1.1、可空性

  在 Kotlin 中,类型系统区分一个引用是可以容纳 null (可空引用)还是不能容纳(非空引

  用)。 例如,String 类型的常规变量不能指向 null

  var name: String = leavesC

  //编译错误

  //name = null

  如果希望一个变量可以储存 null 引用,需要显式地在类型名称后面加上问好来标记它:

  var name: String? = leavesC

  name = null

  问号可以加在任何类型的后面来表示这个类型的变量可以存储 null 引用:Int?、Doubld? 、Long? 等

扫描二维码关注公众号,回复: 6449406 查看本文章

  Kotlin 对可空类型的显式支持有助于防止 NullPointerException 导致的异常问题,编译器不允许不对可空变量做 null 检查就直接调用其属性

  fun check(name: String?): Boolean {

  //编译器不允许不对 name 做 null 检查就直接调用其属性

  return name.isNotEmpty()

  }

  需要显式地进行 null 检查

  fun check(name: String?): Boolean {

  if (name != null) {

  return name.isNotEmpty()

  }

  return false

  }

  1.2、安全调用运算符:?.

  安全调用运算符:?. 允许把一次 null 检查和一次方法调用合并为一个操作,如果变量值非空,则方法或属性会被调用,否则直接返回 null

  例如,以下两种写法是完全等同的:

  fun check(name: String?) {

  if (name != null) {

  println(name.toUpperCase())

  } else {

  println(null)

  }

  }

  fun check(name: String?) {

  println(name?.toUpperCase())

  }

  1.3、Elvis 运算符:?:

  Elvis 运算符:?: 用于替代 ?. 直接返回默认值 null 的情况,Elvis 运算符接收两个运算数,如果第一个运算数不为 null ,运算结果就是其运算结果值,如果第一个运算数为 null ,运算结果就是第二个运算数

  例如,以下两种写法是完全等同的:

  fun check(name: String?) {

  if (name != null) {

  println(name)

  } else {

  println(default)

  }

  }

  fun check(name: String?) {

  println(name ?: default)

  }

  1.4、安全转换运算符:as?

  安全转换运算符:as? 用于把值转换为指定的类型,如果值不适合该类型则返回 null

  fun check(any: Any?) {

  val result = any as? String

  println(result ?: println(is not String))

  }

  1.5、非空断言:!!

  非空断言用于把任何值转换为非空类型,如果对 null 值做非空断言,则会抛出异常

  fun main(args: Array) {

  var name: String? = leavesC

  check(name) //7

  name = null

  check(name) //KotlinNullPointerException

  }

  fun check(name: String?) {

  println(name!!.length)

  }

  1.6、let 函数

  let 函数可用于在表达式不为 null 时才执行指定代码块

  fun main(args: Array) {

  var name: String? = leavesC

  check(name) //leavesC

  name = null

  check(name) //什么都不会输出

  }

  fun check(name: String?) {

  name?.let {

  println(name)

  }

  }

  1.7、可空类型的扩展

  为可空类型定义扩展函数是一种更强大的处理 null 值的方式,可以允许接收者为 null 的调用,并在该函数中处理 null ,而不是在确保变量不为 null 之后再调用它的方法

  例如,如下方法可以被正常调用而不会发生空指针异常

  val name: String? = null

  println(name.isNullOrEmpty()) //true

  isNullOrEmpty() 的方法签名如下所示,可以看到这是为可空类型 CharSequence? 定义的扩展函数,方法中已经处理了方法调用者为 null 的情况

  @kotlin.internal.InlineOnly

  public inline fun CharSequence?.isNullOrEmpty(): Boolean {

  contract {

  returns(false) implies (this@isNullOrEmpty != null)

  }

  return this == null || this.length == 0

  }


转载于:https://juejin.im/post/5ceb95a16fb9a07eda02f5ed

猜你喜欢

转载自blog.csdn.net/weixin_33890526/article/details/91457165