2.7--空指针检查

2.7.1 可空类型系统

在Kotlin中需要一个函数如果不特殊处理需要传入的参数,那么这个参数默认是不可以为空的,Kotlin在编译时就会进行有判空检测,几乎杜绝了空指针异常,如果我们传入的参数为null ,那么编译器会提示错误!那么我们如果需要这个参数可以为空怎么办???其实很简单,只要在函数需要传入参数的类型后面加入一个?问号 就表示该参数可为空!例如:

fun doStudy(study: Study?){
    if (study != null){
        study.readBooks()
        study.doHomework()
    }
}

这里需要注意的是,由于Kotlin 的编译时判空机制,如果我们允许了这个参数为空,那么我们使用的时候一定要对这个参数做判空处理,避免空指针,如果不做处理是不可以运行的,会报错。

2.7.2 判空辅助工具

在Kotlin 中还有比if 判空语句更加简单的写法,就是使用 ?. 来判空,当调用某个类的函数时候,我们可以直接变量?. 函数,如果这个变量是空的,就不会执行后面的函数啦,这样就避免了空指针例如:

fun doStudy(study: Study?){
        study?.readBooks()
        study?.doHomework()
}

如果要判断一个参数是否为空,如果不为空执行一个逻辑,是空的话执行另一个逻辑怎么做呢?if else?? 当然Kotlin 也给我们准备了另一个操作符 ?:,在这个操作符的左面参数是判断条件,如果不为空 那么返回左面参数,如果是空的,返回右面参数:

fun doStudy(study: Study?){
    val any = study ?: "空的"
    println(any)
}

如果我们需要一函数来获得文本长度,那么我们可以这样编写:

fun getTextLength(text:String?):Int = text?.length ?: 0

如果是常规的if else 判断相信可比这样的代码复杂多了,由于Kotlin 的机制在函数只有一行代码的时候可以省略函数体而用= 连接代码的规则使得代码更加的简化,首先我们的参数是一个带?的参数,说明这个参数可以为空,接下来我们需要调用text.length 拿到文本的长度,所以必须先做一个text非空判断,如果text 为空,那么 text.length 也是空的 ,那么根据 ?: 操作符就知道需要返回哪部分了。如果不给text做非空判断,可能会有空指针的产生,所以编译器Kotlin 是不允许的!

Kotlin 也并不是那么智能,如果我们在调用一个函数的时候使用了全局变量,并且做了非空判断,而函数内没有做非空判断,这样也是无法运行的:

val content:String? = "hello word"
fun main() {
    if (content != null){
        printUpperCase()
    }
}
fun printUpperCase(){
    val toUpperCase = content.toUpperCase()
    println(toUpperCase)
}

 这里val toUpperCase = content.toUpperCase() 就会提示我们没有做非空判断,但是实际上我们已经做了非空判断了,我们该如何面对这样的问题呢,可以通过非空断言工具 对这行代码让Kotlin 强制不做非空判断,写法就是在参数后面使用 !!.

fun printUpperCase(){
    val toUpperCase = content!!.toUpperCase()
    println(toUpperCase)
}

不太推荐这种写法,除非对自己的判断足够自信。如果一旦控制正就会导致程序崩溃。

这里来介绍一个比较与众不同的辅助工具 letlet 既不是关键字,也不是操作符,它是一个函数,这个函数提供了 函数式API的编程接口 ,它的函数式 { 参数 : 参数类型 -> 函数体 } ,它的参数就是传入本体!我们可以在函数体内对本体做任何事情拉。这样的好处就是比如我们需要判断一个条件或者一个关键的参数是不是为空,如果不为空,我们就需要做一些列的逻辑,而不是单向的返回什么,那么就需要这个 函数了。

fun doStudy(study: Study?){
    study?.let {
        it.doHomework()
        it.readBooks()
    }
}

运用之前学过的知识直接简化。首先我们做了.?非空判断,然后执行了let 函数,里面写了Lambda 表达式,表达式执行了对应的函数。用了let 函数之后,就可以直接调用逻辑代码了,就不需要再去调用其他函数再做非空判断。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值