我如何使用let检查2个条件(或应用等)

时间:2019-10-30 20:21:57

标签: kotlin

是否有更惯用的方式写以下内容?

foo?.let{
        if(!foo.isBlank()) {
            bar?.let { 
                if(!bar.isBlank()) {
                    println("foo and bar both valid strings")
                }
            }
        }
    }

基本上,这个想法是两个字符串都应该为nonNull和nonEmpty,我想知道是否还有比if(foo.isNullOrEmpty && !bar.isNullOrEmpty)更好的Kotlin方式

6 个答案:

答案 0 :(得分:3)

使用此

fun <T, R, S> biLet(lhs: T, rhs: R, block: (T, R) -> S): S? = if (lhs != null && rhs != null) block(lhs, rhs) else null

用作

biLet(foo, bar) { safeFoo, safeBar ->
}

编辑:字符串的变体

fun <T: CharSequence?, S> biLet(lhs: T, rhs: T, block: (T, T) -> S): S? =
    if (lhs.isNotNullOrBlank() && rhs.isNotNullOrBlank()) block(lhs, rhs) else null

答案 1 :(得分:2)

您可以使用sequenceOfnone

if (sequenceOf(foo, bar).none { it.isNullOrBlank() }) {
    println("foo and bar both valid strings")
}

答案 2 :(得分:1)

在某处使用lambda声明扩展功能,例如:

inline fun String.ifNotEmpty(bar: String, function: () -> Unit) {
    if (this.isNotEmpty() && bar.isNotEmpty()) {
        function.invoke()
    }
}

并将其用作:

val foo = "foo-value"
val bar = "bar-value"

foo.ifNotEmpty(bar) {
    println("foo and bar both valid strings")
}

答案 3 :(得分:1)

改进@Francesc的答案,我创建了nLet版本

fun <S> nLet(vararg ts: Any?, block: (Array<out Any?>) -> S): S? = 
    if (ts.none { when (it) { is String -> it.isNullOrEmpty() else -> it == null } }) block(ts) else null

您可以像这样使用它

nLet (1, 2 , 3, "a", "B", true) { ts ->
    ts.forEach { println(it) }
}

答案 4 :(得分:0)

这是我使用的:

fun <P1, P2, R> nLet(p1: P1?, p2: P2?, block: (P1, P2) -> R?): R? = 
    p1?.let { p2?.let { block(p1, p2) } }

用法:

nLet(foo, bar) { f, b -> doStuff(f, b) }

如果需要更多参数,请添加更多带有P的nLet函数。

答案 5 :(得分:0)

您也可以将其用于任意数量的参数:

fun <P, R> nLet(vararg ts: P?, block: (Array<out P?>) -> R): R? = 
    ts.takeIf { it.none { it == null } }?.let { block(it) }

用法:

nLet(foo, bar, dog) { (f, b, d) -> doStuff(f, b, d) }

这有效,但是fbd将具有可为空的类型,即使它们不能为空。

(解决这个问题的方法可能很聪明...)