列表包含可以在Kotlin中为可空列表的可空值

Phi*_*orf 4 kotlin

我有一个List<T?>包含空值(我想,这是不被禁止的).如果此列表的一个元素为null,我希望整个列表为null(Haskell人们称之为sequence).以下伪代码演示了我想要做的事情:

fun <T> sequence(a : List<T?>) : List<T>? {
    return 
        a.fold(
            listOf(),
            { 
                prevArray, element -> 
                    if(element == null) null else prevArray + element 
            })
}
Run Code Online (Sandbox Code Playgroud)

这是伪代码,因为编译器抱怨这一点Null can not be a value of a non-null type kotlin.collections.List<T>.

什么是在Kotlin表达我想要的东西的惯用方式?使用Java的Optional类型,这至少是可编译的:

fun <T> sequence(a : List<T?>) : Optional<List<T>> {
    return 
        a.fold(
            Optional.of(listOf()),
            { 
                prevArray, element -> 
                    if(element == null) Optional.empty<List<T>>() else Optional.of(prevArray + element) 
            })
}
Run Code Online (Sandbox Code Playgroud)

但是Kotlin在null处理方面有许多运算符和功能,所以我认为直接使用null会更加惯用.

Ale*_*lov 11

您可以使用非本地返回从sequence函数返回:

fun <T> sequence(a: List<T?>): List<T>? {
    return a.fold(listOf()) {
        prevArray, element ->
        if (element == null) return null else prevArray + element
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,我将使用简单if表达式解决您所描述的问题,以防止发生大量列表分配,因为列表添加会为每个元素创建一个由数组支持的新列表.未经检查的强制转换警告在下面被抑制,因为编译器无法确定该列表在该点没有包含空值,尽管我们可以清楚地看到这种情况:

fun <T> sequence(a: List<T?>): List<T>? {
    @Suppress("UNCHECKED_CAST")
    return if (a.any { it == null }) null else a as List<T>
}
Run Code Online (Sandbox Code Playgroud)