当对象为 null 时何时使用 let/run/apply/with/also?
When to use let/run/apply/with/also when an object is null?
我想运行一段代码取决于变量是否为空,但我仍然不知道什么时候使用let,运行...等等
我想要这样的东西:
myVar?.xxx{
// do something if is not null
} ?: xxx{
// do something is myVar is null
}
什么是最好的选择,为什么?谢谢:)
PS 我已经读过 但我仍然不知道什么是最佳做法
最佳做法是不 将范围函数与Elvis 运算符链接起来以处理null/not null,因为它的可读性较差且容易出错。仅仅因为您可以 做某事并不意味着您应该做!内联作用域函数提供了强大的功能,因此也有很大的误用和代码可读性差的可能性。
例如,第一个范围函数的 return 值(如果它是 let
或 run
)可能为 null 并导致第二个范围函数也为 运行 和 return 与您预期的不同。
您链接的问题是旧问题,并且从那时起就有很多新的 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
函数不是 return 结果,而是 return 它被调用的结果,因此不存在意外触发两个范围函数的风险。 apply
也可以,但通常如果您有一整块代码到 运行,您不希望将其用作接收器。那将不太可读。对于第二个作用域函数,run
最有意义,因为它不会从外部作用域更改接收器,因此它在这里对可读性造成的影响最小。
我想运行一段代码取决于变量是否为空,但我仍然不知道什么时候使用let,运行...等等
我想要这样的东西:
myVar?.xxx{
// do something if is not null
} ?: xxx{
// do something is myVar is null
}
什么是最好的选择,为什么?谢谢:)
PS 我已经读过
最佳做法是不 将范围函数与Elvis 运算符链接起来以处理null/not null,因为它的可读性较差且容易出错。仅仅因为您可以 做某事并不意味着您应该做!内联作用域函数提供了强大的功能,因此也有很大的误用和代码可读性差的可能性。
例如,第一个范围函数的 return 值(如果它是 let
或 run
)可能为 null 并导致第二个范围函数也为 运行 和 return 与您预期的不同。
您链接的问题是旧问题,并且从那时起就有很多新的 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
函数不是 return 结果,而是 return 它被调用的结果,因此不存在意外触发两个范围函数的风险。 apply
也可以,但通常如果您有一整块代码到 运行,您不希望将其用作接收器。那将不太可读。对于第二个作用域函数,run
最有意义,因为它不会从外部作用域更改接收器,因此它在这里对可读性造成的影响最小。