我有一个类:
class Clazz(
val name: String?,
val value0: String,
val value1: String?,
val value2: String
)
如果我们有非空名称,我想打印value0
。但是如果name
为null,那么只有当它不为null时,我才希望返回value1
。如果是,则返回value2
。
我用let
的方式:
val result =
clazz.name?.let {
return clazz.value0
} ?: run {
clazz.value1 ?: clazz.value2
}
但我认为这是相当糟糕的代码,它可以做得更好、更简单。是这样的方式吗?
试试下面的代码,它会起作用:
代码:
val result: String = when {
clazz.name.isNullOrEmpty() -> {
clazz.value1 ?: clazz.value2
}
else -> {
clazz.value0
}
}
解释:
val result: String = when {
// check name is null --> true
clazz.name.isNullOrEmpty() -> {
// check value1 is not null, if null then return value2
clazz.value1 ?: clazz.value2
}
else -> { // name is not nul so it will return value0
clazz.value0
}
}
您基本上会遇到这样的情况:您有一个备选方案列表(value0
、value1
、value2
(,并且您想要选择第一个非null的备选方案。value0
不太适合,但我们可以像您尝试的那样使用?.let
使其适合,或者通常使用takeIf
使任何条件适合。
然后你可以写下你的备选方案,并用elvis算子?:
:将其分离
clazz.value0.takeIf { clazz.name != null } ?: // or clazz.name?.let { clazz.value0 }
clazz.value1 ?:
clazz.value2
您还可以将clazz
提取到run
:中
clazz.run {
value0.takeIf { name != null } ?:
value1 ?:
value2
}
这读起来就像英语:
如果
name
不为空,则取value0
,否则如果value1
不为空。否则为CCD_ 18。
在Kotlin中,if
可以用作表达式(类似于when
(。而且它通常比?.let {..} ?: run {..}
更可读。你可以这样使用它:
val result = if (clazz.name != null) {
clazz.value0
} else {
clazz.value1 ?: clazz.value2
}
现在,就像通常的情况一样,像这样孤立的逻辑片段最好被提取到一个单独的函数中。所以我建议在Clazz
:上的扩展函数中提取这篇文章
val result = clazz.meaningfulNameForThis()
private fun Clazz.meaningfulNameForThis() = if (name != null) {
value0
} else {
value1 ?: value2
}