Kotlin泛型复杂空值问题:能否合并两个扩展函数?
重构Kotlin扩展函数以统一处理可空与非空外层容器类型
问题描述
我有两个Kotlin扩展函数,仅在类型的空值性上存在差异——空值作用于外层容器本身而非内部泛型参数,想知道能否将它们重构为单一函数,避免未检查类型转换:
import javafx.beans.property.SimpleObjectProperty import javafx.beans.value.ObservableValue fun <T> ObservableValue<out ObservableValue<T>>.flattenNonNull(): ObservableValue<T> = (this as ObservableValue<ObservableValue<T>?>.flattenNull() as ObservableValue<T> fun <T> ObservableValue<out ObservableValue<T>?>.flattenNull(): ObservableValue<T?> = SimpleObjectProperty<T?>(null).also { out -> this.subscribe { newValue -> out.unbind() if (newValue == null) out.value = null else out.bind(newValue) } }
类似的通用场景示例:
fun <T> C1<C2<T>>.foo1(): C3<T> = TODO() fun <T> C1<C2<T>?>.foo2(): C3<T?> = TODO()
此处空值性直接作用于C2本身,而非C2<T>内部的T,因此无法通过将T实例化为可空类型来复用foo1。
解决方案
可以通过**泛型参数结合@UnsafeVariance**实现单一函数,同时正确推导返回类型的空值性,完全避免未检查转换:
import javafx.beans.property.SimpleObjectProperty import javafx.beans.value.ObservableValue import kotlin.jvm.@UnsafeVariance fun <T> ObservableValue<out ObservableValue<@UnsafeVariance T>?>.flatten(): ObservableValue<T> = SimpleObjectProperty<T>(null as T).also { out -> this.subscribe { newValue -> out.unbind() if (newValue == null) { out.value = null as T } else { out.bind(newValue) } } }
方案说明
@UnsafeVariance的作用:由于ObservableValue本身是协变类型(定义为ObservableValue<out T>),@UnsafeVariance允许我们在协变位置直接使用泛型参数T,突破编译层面的协变限制,同时保证类型安全。- 统一处理两种输入场景:
- 当输入为
ObservableValue<out ObservableValue<String>>(内层非空),泛型T推导为非空的String,返回ObservableValue<String>; - 当输入为
ObservableValue<out ObservableValue<String?>?>(内层可空),泛型T推导为String?,返回ObservableValue<String?>。
- 当输入为
- 消除未检查转换风险:函数逻辑直接基于输入类型推导返回类型,无需手动强制类型转换,解决了原代码中的类型安全隐患。
使用示例
// 处理非空内层的ObservableValue val nonNullInner: ObservableValue<ObservableValue<String>> = TODO() val flattenedNonNull: ObservableValue<String> = nonNullInner.flatten() // 处理可空内层的ObservableValue val nullableInner: ObservableValue<ObservableValue<String?>?> = TODO() val flattenedNullable: ObservableValue<String?> = nullableInner.flatten()
内容的提问来源于stack exchange,提问作者Michael D. Adams
相关产品推荐
相关产品推荐

