科特林和?Let: 如何选择变量字段的变体?



我有一个类:

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
}
}

您基本上会遇到这样的情况:您有一个备选方案列表(value0value1value2(,并且您想要选择第一个非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
}

相关内容

  • 没有找到相关文章

最新更新