?. 操作符与let函数
if (study != null){
study.learnMath()
study.learnEnglish()
}
我们可以用下列写法代替:
study?.learnMath()
study?.learnEnglish()
这样,我们就利用?.
吧if
语句代替掉了。
?: 操作符
此操作符左右两边都接受一个表达式,左表达式结果不为空就返回左边表达式的结果,否则返回右边表达式的结果。例如:
val c = a ?: b
下面我们通过具体例子来结合使用:
比如我们要计算一段文本的长度,我们可能会有如下写法:
fun getStringLength(text: String?):Int{
if (text != null){
return text.length
}
return 0
}
由于文本是可能为空的,因此我们需要先进行判空操作。但我们依然可以利用操作符使代码更加简单:
fun getStringLength(text: String?) = text?.length ?: 0
这里我们用到?.
和?:
操作符,首先?.
判断text
是否为空,若为空返回null,再利用?:
将null转为0,进行输出。
机器不是万能的,当我们非常确信排除了所有的空指针异常,kotlin编译仍然报错,我们可是在对象后面加上!!
,让编译器跳过检查。例如:
val fruit = apple!!.toUpperCase()
let函数
let
函数提供了函数式API的编程接口,将原始调用的对象作为参数传给Lambda表达式:
object.let{objectCopy ->
//具体业务逻辑
}
这里调用了名为object
对象的let
函数,Lambda表达式会立即执行对应代码。当然objectCopy
与object
是同一个对象,这里为了防止变量重名。
let
函数与?.
操作符可以在空指针检查时起很大作用。
我们回到一开始学习时写的函数:
fun tuDo(study:Study?){
study?.learnMath()
study?.learnEnglish()
}
虽然可以正常编译,可是很啰嗦,每次调用study
都会判断是否为空,这时我们就可以对以上代码进行优化:
fun tuDo(study:Study?){
study?.let {studyCopy ->
studyCopy.learnMath()
studyCopy.learnEnglish()
}
}
当?.
判断为空时什么都不做,对象不为空时就调用let
函数。而let
函数会将study对象本身作为参数传递给Lambda表达式,此时我们即可放心使用表达式。
还有一点,let函数可以处理全集变量的判空变量。而if不能,因为全局变量随时可被其他线程所修改,即使判空,仍无法保证没有空指针风险,而使用let函数不会。例:
欢迎关注小试编程