我在代码中用let块替换了所有空检查,
1.带空检查的代码示例:
if(someValue != null){//run if someValue is not null}
else {//run if someValue is null}
Run Code Online (Sandbox Code Playgroud)
2.如果进行空检查,则使用let-run块后的代码库;
var someValue : String? = null
someValue = "SOF"
someValue?.let {safeSomeValue->
//This code block will run only if someValue is not null
}?.run {
//This code block should run only when if someValue is null, like else condition
}
Run Code Online (Sandbox Code Playgroud)
现在,让运行块的问题在于,即使someValue不为null,两个代码块也在运行。因此,我无法将代码示例1中if-else条件的行为复制到代码示例2中的run-let条件。
预期的行为是根据value为null或not null来执行let或run代码块。
Arp*_*ogi 11
来源 - kotlinlang.org
改变?。with ?:将解决这个问题,
代码库如下,将根据空检查运行 let 或 run 块。
var someValue : String? = null
someValue = "SOF"
someValue?.let {safeSomeValue->
//This code block will run only if someValue is not null
}?:run {
//This code block will run only when if someValue is null, like else condition
}
Run Code Online (Sandbox Code Playgroud)
您可以创建一个扩展函数,如下所示
fun <T> T?.whenNull(block: () -> Unit) = this ?: block()
Run Code Online (Sandbox Code Playgroud)
然后你就这样称呼它
somevalue?.let { safeSomeValue ->
// TODO
}.whenNull {
// execute when someValue is null
}
Run Code Online (Sandbox Code Playgroud)
I am replacing all the null check with let block in my code
The first question here is, why? Is this somehow more readable for you than the regular if-else structure? I'd be generally wary of refactoring just for refactoring's sake.
The second consideration is much more important: this conversion you're doing is not equivalent to the original code, you're actually modifying the behavior with this change. Take the following piece of code:
var someValue : String? = null
someValue = "SOF"
someValue?.let {safeSomeValue->
foo(someSafeValue)
bar(someSafeValue)
} ?: run {
println("shouldn't happen if someValue != null")
}
Run Code Online (Sandbox Code Playgroud)
You expect the run block to execute only if someValue == null, but that's actually not the only case when it will run. The entire someValue?.let { ... } expression can produce null values not just when someValue itself was null, but also if the block passed to let returned null. In this case, if the bar() function call results in null, the run statement will be executed afterwards, therefore running both branches of what you thought was a fancied up if-else statement.
举一个非常具体的例子来说明 zsmb13 的回答所谈论的内容:
val someValue = 0
someValue?.let { safeSomeValue->
println("then")
null
} ?: run {
println("else")
}
Run Code Online (Sandbox Code Playgroud)
打印then和else。您可以使用also代替来解决此问题let:
val someValue = 0
someValue?.also { safeSomeValue->
println("then")
null
} ?: run {
println("else")
}
Run Code Online (Sandbox Code Playgroud)
只会打印then. 阅读https://kotlinlang.org/docs/reference/scope-functions.html并找出原因并证明它确实总是与原始if ... else. 但我也同意 zsmb13 这可能是一个坏主意。
| 归档时间: |
|
| 查看次数: |
70 次 |
| 最近记录: |