val dialog: Dialog? = Dialog()
dialog?.dismiss() // If the dialog is null, the dismiss call will be omitted
Let函数
user?.let {
// Work with non-null user
handleNonNullUser(user)
}
提前退出
fun handleUser(user: User?) {
user ?: return // Exit the function if user is null
// Now the compiler knows user is non-null
}
不可改变的阴影
var user: User? = null
fun handleUser() {
val user = user ?: return // Return if null, otherwise create immutable shadow
// Work with a local non-null variable named user
}
默认值
fun getUserName(): String {
// If our nullable reference is not null, use it, otherwise use non-null value
return userName ?: "Anonymous"
}
/**
* Performs [R] when [T] is not null. Block [R] will have context of [T]
*/
inline fun <T : Any, R> ifNotNull(input: T?, callback: (T) -> R): R? {
return input?.let(callback)
}
/**
* Checking if [T] is not `null` and if its function completes or satisfies to some condition.
*/
inline fun <T: Any> T?.isNotNullAndSatisfies(check: T.() -> Boolean?): Boolean{
return ifNotNull(this) { it.run(check) } ?: false
}
下面是如何使用这些功能的可能示例:
var s: String? = null
// ...
if (s.isNotNullAndSatisfies{ isEmpty() }{
// do something
}
我想回应@Benito Bertoli和@BingLi224的答案,并提供imho正确的解决方案。 问题是使用let,因为let的结果是它的最后一个表达式。你只想传递和传入它的相同的东西,所以also是一个更好的解决方案。同时,在使用elvis操作符后,let无法使用,因为没有对象可以调用扩展函数,所以我使用run(函数版)。更多关于scope functions official documentation 与使用if/when相比,另一个缺点是不能将其用作表达式,因此我不建议使用它:-) 最终代码:
"test"?.also {
println("1. it=$it")
} ?: run {
println("2. it is null!")
}
"test"?.also {
println("1. it=$it")
null
} ?: run {
println("2. it is null!")
}
null?.also {
println("1. it is null!")
} ?: run {
println("2. it is null")
}
null?.also {
println("1. it is null!")
null
} ?: run {
println("2. it is null")
}
6条答案
按热度按时间mkshixfv1#
结构等式
a == b
被转换为因此,当与
null
进行比较时,结构等式a == null
被转换为引用等式a === null
。根据docs,优化代码没有意义,因此可以使用
a == null
和a != null
注意,如果变量是可变属性,您将无法在
if
语句中将其智能转换为不可为空的类型(因为该值可能已被另一个线程修改),您必须使用安全调用操作符与let
。安全呼叫话务员
?.
您可以将其与Elvis操作符结合使用。
猫王运算符
?:
(我猜是因为审讯痕迹像猫王的头发)如果你想运行一段代码
两者结合
iovurdzv2#
Kotlin处理null的方式
安全访问操作
Let函数
提前退出
不可改变的阴影
默认值
使用瓦尔而不是var
val
是只读的,var
是可变的。建议使用尽可能多的只读属性,它们是线程安全的。使用lateinit
有时候你不能使用不可变的属性。例如,在Android上,当在
onCreate()
调用中初始化某个属性时,就会发生这种情况。对于这些情况,Kotlin有一个名为lateinit
的语言功能。qltillow3#
这两种方法都生成相同的字节码,因此您可以选择任何您喜欢的。
u3r8eeie4#
添加到@Benito Bertoli,
这个组合实际上不同于if-else
结果是:
但如果:
结果是:
另外,如果先使用elvis:
结果是:
balp4ylt5#
查看有用的方法,它可能是有用的:
下面是如何使用这些功能的可能示例:
gt0wga4j6#
我想回应@Benito Bertoli和@BingLi224的答案,并提供imho正确的解决方案。
问题是使用
let
,因为let
的结果是它的最后一个表达式。你只想传递和传入它的相同的东西,所以also
是一个更好的解决方案。同时,在使用elvis操作符后,let
无法使用,因为没有对象可以调用扩展函数,所以我使用run
(函数版)。更多关于scope functions official documentation与使用
if
/when
相比,另一个缺点是不能将其用作表达式,因此我不建议使用它:-)最终代码:
和输出: