2016-03-11 68 views
4

我有一個包含空值(我想這不是禁止的)的List<T?>。如果此列表中的一個元素爲空,我希望整個列表都爲null(Haskell人稱爲sequence)。下面的僞代碼演示了什麼,我想做的事:在Kotlin中包含可爲空的列表的可爲空值的列表

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

這是僞代碼,因爲編譯器抱怨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) 
      }) 
} 

但科特林有許多運營商和功能有關空處理,所以我想用空直接會更地道。

回答

12

您可以使用non-local returnsequence函數返回:

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

不過,我解決了一個簡單的if -expression描述的問題,以防止大量的名單分配其發生,因爲名單另外爲每個元素創建一個由數組支持的新列表。未選中的鑄警告被抑制之下,因爲編譯器無法弄清楚,列表不會在這一點上包含空值,雖然我們可以清楚地看到是這樣的話:

fun <T> sequence(a: List<T?>): List<T>? { 
    @Suppress("UNCHECKED_CAST") 
    return if (a.any { it == null }) null else a as List<T> 
} 
+0

注意,使用第二個變種,你必須請確保列表'a'不會在後面添加新的'null'元素。 – Ilya

+0

或者你可以複製一次,以避免@ilya提到的問題 – voddan

相關問題