处理惯用函数链中的空列表

117*_*174 2 generics kotlin

我刚接触 Kotlin 大约 2 周,我对函数式编程非常感兴趣,我不确定这部分是否遗漏了 FP 中的一个基本习语,因为我想处理像从存储库中检索结果这样的样板文件,如果结果是一个空列表然后我想要一个日志语句并希望其他链式调用停止。一般来说,为什么(至少对我来说不明显)不是处理空列表的函数?像下面这样?问这个问题,我可能可以省略“这个”空检查。

fun <E : Any, T : List<E>> T?.ifEmpty(func: () -> Unit): List<E> {
    if (this == null || this.isEmpty()) {
        func()
        return emptyList()
    }
    return this
}

fun <E : Any, T : List<E>> T?.ifNotEmpty(func: (List<E>) -> Unit): List<E> {
    if (this != null && !this.isEmpty()) {
        func(this)
        return this
    }
    return emptyList()
}

fun <E : Any, F: Any, T : List<E>> T?.mapIfNotEmpty(func: (List<E>) -> (List<F>)): List<F> {
    if (this != null && !this.isEmpty()) {
        return func(this)
    }
    return emptyList()
}
Run Code Online (Sandbox Code Playgroud)

小智 5

  • ifEmpty 从 Kotlin 1.3 (kotlin.collections) 开始可用。

  • 如果非空

看起来像无用的函数,大多数情况下我们遍历列表,如果列表为空,我们的代码将不会执行。所以,例如

list.ifNotEmpty { do sth with whole list. sth like iteration? mapping? }
Run Code Online (Sandbox Code Playgroud)

有同样的效果

list.forEach { do sth with only one element and nothing if list is empty }
list.map { map every element to other object } 
Run Code Online (Sandbox Code Playgroud)

如果这还不够,那么你可以这样写:

list.takeIf { it.isNotEmpty() }?.apply|let // unfortunately it looks ugly
Run Code Online (Sandbox Code Playgroud)

有完全相同的结果。