java中示例
public void doStudy(Study study) {
if (study != null) {
study.readBooks();
study.doHomework();
}
}
可空类型系统
Kotlin非常科学地解决了这个问题,它利用编译时判空检查的机制几乎杜绝了空指针异常
fun doStudy(study: Study) {
study.readBooks()
study.doHomework()
}
看上去和Java一样可能会接受一个参数为null,但实际上它是没有空指针风险的,
因为Kotlin默认所有的参数和变量都不可为空,所以这里传入的Study参数也一定不会为空,
如果向doStudy()函数传入一个null参数,则会报错
也就是说,Kotlin将空指针异常的检查提前到了编译时期
如果我们的业务逻辑就是需要某个参数或者变量为空该怎么办呢?
Kotlin提供了另外一套可为空的类型系统
可为空的类型系统是什么样的呢? 就是在类名的后面加上一个问号。
比如,Int表示不可为空的整型,而Int?就表示可为空的整型
fun doStudy(study: Study?) {
if (study != null) {
study.readBooks()
study.doHomework()
}
}
判空辅助工具
?. 操作符
if (a != null) {
a.doSomething()
}
// 使用?.操作符就可以简化成:
a?.doSomething()
fun doStudy(study: Study?) {
study?.readBooks()
study?.doHomework()
}
?: 操作符
这个操作符的左右两边都接收一个表达式,
如果左边表达式的结果不为空就返回左边表达式的结果,
否则就返回右边表达式的结果
val c = if (a != null) {
a
} else {
b
}
// 使用?:操作符就可以简化成:
val c = a ?: b
fun getTextLength(text: String?): Int {
if (text != null) {
return text.length
}
return 0
}
// 使用?:操作符就可以简化成:
fun getTextLength(text: String?) = text?.length ?: 0
!! 操作符
fun printUpperCase() {
val upperCase = content!!.toUpperCase()
println(upperCase)
}
这是—种有风险的写法,意在告诉Kotlin,我非常确信这里的对象不会为空
如果出现问题,你可以直接拋出空指针异常,后果由我自己承担。
辅助工具 let
let既不是操作符,也不是什么关键字,而是—个函数。
这个函数提供了函数式API的编程接口,并将原始调用对象作为参数传递到Lambda表达式中
let函数属于Kotlin中的标准函数
示例代码如下:
obj.let { obj2 ->
// 编写具体的业务逻辑
}
这里调用了obj对象的let函数,然后Lambda表达式中的代码就会立即执行,
并且这个obj对象本身还会作为参数传递到Lambda表达式中。
不过,为了防止变量重名,这里我将参数名改成了obj2,
但实际上它们是同—个对象,这就是let函数的作用。
其实let函数的特性配合 ?.操作符 可以在空指针检查的时候起到很大的作用
fun doStudy(study: Study?) {
study?.let { stu ->
stu.readBooks()
stu.doHomework()
}
}
当Lambda表达式的参数列表中只有—个参数时,可以不用声明参数名,直接使用it关键字来代替即可
可简化为:
fun doStudy(study: Study?) {
study?.let {
it.readBooks()
it.doHomework()
}
}
共同學習,寫下你的評論
評論加載中...
作者其他優質文章