如何修复Kotlin中扩展函数与类型边界引发的重载解析歧义
Kotlin泛型限制下Option.getOrNull的重载歧义问题解决
我想要定义一个Option类型,并伪多态地实现getOrNull操作。以下代码原本运行正常:
sealed interface Option<out T> data class Some<out T>(val value: T): Option<T> object None: Option<Nothing> fun <T> Option<T>.getOrNull(): T? = when (this) { is Some<T> -> getOrNull() is None -> getOrNull() } fun <T> Some<T>.getOrNull(): T = value fun None.getOrNull(): Nothing? = null
但当我给泛型类型加上<T: Any>限制以禁止Option(null)时:
fun <T: Any> Option<T>.getOrNull(): T? = when (this) { is Some<T> -> getOrNull() // 此处出现重载歧义错误 is None -> getOrNull() }
此时编译器报错:
Kotlin: Overload resolution ambiguity: public fun <T : Any> Option<TypeVariable(T)>.getOrNull(): TypeVariable(T)? defined in root package in file Delme.kt public fun <T> Some<TypeVariable(T)>.getOrNull(): TypeVariable(T) defined in root package in file Delme.kt
解决方法1:对齐子类扩展函数的泛型约束
给Some的getOrNull扩展函数也加上<T: Any>的泛型约束,让它和Option的扩展函数约束保持一致。编译器会优先匹配更具体的Some<T>类型的扩展,从而消除歧义:
sealed interface Option<out T> data class Some<out T>(val value: T): Option<T> object None: Option<Nothing> fun <T: Any> Option<T>.getOrNull(): T? = when (this) { is Some<T> -> getOrNull() is None -> getOrNull() } fun <T: Any> Some<T>.getOrNull(): T = value // 新增<T: Any>约束 fun None.getOrNull(): Nothing? = null
解决方法2:显式指定调用目标
在when分支中,通过显式限定调用的扩展函数,告诉编译器要调用Some类的实现:
fun <T: Any> Option<T>.getOrNull(): T? = when (this) { is Some<T> -> this@Some.getOrNull() // 显式限定调用Some的扩展 is None -> getOrNull() }
解决方法3:直接访问值(简化写法)
既然已经通过is Some<T>完成了类型判断,也可以直接访问value属性,跳过扩展函数调用,写法更简洁:
fun <T: Any> Option<T>.getOrNull(): T? = when (this) { is Some<T> -> value is None -> null }
内容的提问来源于stack exchange,提问作者Duncan McGregor
相关产品推荐
相关产品推荐

