【发布时间】:2020-02-20 16:19:20
【问题描述】:
我正在寻找一种方便的方法来安全地将 List<T?> 转换为 List<T>?(或者,更一般地,将 Iterable<T?> 转换为 Iterable<T>?)而不过滤任何元素。
换句话说,如果所有元素都不为空,则取列表。
在 Swift 中我可以这样做:
let a: [Int?] = [1, nil, 3]
let b: [Int?] = [1, 2, 3]
let aa = a as? [Int] // nil
let bb = b as? [Int] // [1, 2, 3]
在 Kotlin 中,外观相似的代码只是进行未经检查的强制转换,不会导致 aa 成为 null:
val a = listOf<Int?>(1, null, 3)
val b = listOf<Int?>(1, 2, 3)
val aa = a as? List<Int> // [1, null, 3]
val bb = b as? List<Int> // [1, 2, 3]
因此,我正在寻找这样的方法:
@Suppress("UNCHECKED_CAST")
fun <T : Any> Iterable<T?>.takeIfAllNotNull(): Iterable<T>? =
takeIf { all { el -> el != null } } as? Iterable<T>
这样我可以编写如下代码:
val a = listOf<Int?>(1, null, 3)
val b = listOf<Int?>(1, 2, 3)
val aa = a.takeIfAllNotNull() // null
val bb = b.takeIfAllNotNull() // [1, 2, 3]
我一定在这里遗漏了什么。标准库没有这样的方法吗?
【问题讨论】:
-
所以您要的是 Kotlin 解决方案?在这种情况下,您应该不用 [swift] 标记问题——至少我是这样理解 Meta 上的 meta.stackoverflow.com/q/316809/1187415 的。
-
val aa = a as? List<Int> // [1, null, 3]看起来像一个错误 -
它看起来像一个错误,但编译器会警告问题中忽略的不安全强制转换。忽略不安全的强制转换可能会导致运行时类型不正确。
-
@MartinR,[swift] 已删除。感谢您指出这一点。