android - 当对象为空时,何时使用 let/run/apply/with/also?
问题描述
所以我读了如果对象为空,如何运行代码?但我还不知道何时使用 let,run... 等。我想要这样的东西:
myVar?.xxx{
// do something if is not null
} ?: xxx{
// do something is myVar is null
}
最佳做法是什么?谢谢 :)
解决方案
最佳实践是不要将作用域函数与 Elvis 运算符链接来处理 null/not null,因为它的可读性较差并且容易出错。仅仅因为您 可以做某事并不意味着您应该做某事!内联作用域函数提供了很大的功能,因此也有很大的误用和可读性较差的代码的可能性。
例如,第一个作用域函数的返回值(如果它是let
或run
)可能为 null 并导致第二个作用域函数也运行并返回超出您预期的内容。
您链接的问题是旧的,并且从有很多新的 Kotlin 用户开始,因为 Android 采用它作为推荐语言。许多新用户对内联作用域函数感到兴奋,并且可能过于渴望尽可能多地使用它们,而不是仅仅在它们是最合适的工具的地方使用它们。请注意,在显示如何完成的投票最多的答案中,建议仍然使用 if/else,因为这样更具可读性。
如果myVar
是局部变量(或val
没有自定义 getter 的本地定义属性),您应该这样做:
if (myVar != null) {
// myVar will be smart cast to non-null inside this if block.
//TODO
else {
//TODO
}
如果myVar
是一个var
属性,你可以这样做:
myVar.let {
if (it != null) {
// it will be smart cast to non-null inside this if block.
//TODO
else {
//TODO
}
}
// OR
val myLocalVar = myVar
if (myLocalVar != null) {
// myLocalVar will be smart cast to non-null inside this if block.
//TODO
else {
//TODO
}
为了解决您的具体问题,如果您真的决心这样做(而且您不应该这样做!),那么使用myVar.also { } ?: run { }
. 该also
函数不返回结果,而是返回调用它的内容,因此不存在意外触发两个作用域函数的风险。apply
也可以,但是通常如果您要运行整个代码块,则不希望将其用作接收器。那可读性会降低。而对于第二个作用域函数,run
最有意义,因为它不会从外部作用域改变接收器,因此它在这里对可读性造成的摩擦最小。
推荐阅读
- r - In shiny, how to have a new actionButton when a different variable is selected?
- git - 之前将开发合并到我的功能分支后,你能 git 交互式 rebase squash 吗?
- php - Magento 报告问题 - 只有过滤器选项可用,没有表格显示
- java - 如何使用mapstruct将对象映射为字段?
- oracle - 需要更新 sqlplus 中的泰米尔语字体
- oracle - 如何使用 PL/SQL 代码在 Apex Oracle 中显示十进制值
- python - pip 在安装兼容的包版本时是否考虑到实际的 Python 版本?
- android - 在 Espresso 中模拟对象
- android - 删除 kotlin android 中浮点值的科学记数法格式
- java - getFramesAtIndex() 中的 MediaMetadataRetriever.BitmapParams 参数是什么?