Generics Kotlin泛型返回类型与接收方匹配
我正在尝试创建一个函数,如果接收器的数字为空,则返回默认值。但是,当我检查接收值的类型时,它与接收方不匹配,而是与作为参数传递的默认值匹配Generics Kotlin泛型返回类型与接收方匹配,generics,kotlin,Generics,Kotlin,我正在尝试创建一个函数,如果接收器的数字为空,则返回默认值。但是,当我检查接收值的类型时,它与接收方不匹配,而是与作为参数传递的默认值匹配 fun <T : Number> T?.orDefault(value: T): T = this ?: value 当我尝试引入另一个扩展T的J时,仍然失败。使用上述主方法运行仍然失败 fun <T : Number, J : T> T?.orDefault(value: J): T = this ?: (value as T)
fun <T : Number> T?.orDefault(value: T): T = this ?: value
当我尝试引入另一个扩展T
的J
时,仍然失败。使用上述主方法运行仍然失败
fun <T : Number, J : T> T?.orDefault(value: J): T = this ?: (value as T)
// Output:
-1
java.lang.Integer
fun T?.orDefault(值:J):T=this?:(值为T)
//输出:
-1
java.lang.Integer
在所有情况下,它都不会返回双精度。这里怎么了
编辑:
我最后做了这样的事情:
// Output:
-1
java.lang.Integer
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
fun T?.orDefault(值:J):T=this?:(值为T)
这样,它可以确保返回类型与接收方类型相同。然而,唯一的缺点是空
Int
接收器默认接受Double
,并强制转换为Int
返回。在第一种情况下,orDefault()
要求接收器和参数的类型相同(T
)。因此,当您使用Double
接收器和Int
参数调用它时,编译器会为类型参数T
推断出它们最接近的公共超类(Number
)。然后它直接返回给定的Int
,如您所见
虽然你的第二个案例看起来更像你想要的,但我认为它仍然在为T
推断Number
,所以演员阵容没有任何效果
归根结底,我认为您不可能只用一个扩展函数就可以做您想做的事情。在Kotlin中不能将
Int
转换为Double
(与Java不同);您需要调用它的toDouble()
方法。您需要为每种接收器类型分别编写代码。泛型不是最佳解决方案。由于Number
只有7个子类,因此最好像这样重载扩展函数:
// Output:
-1
java.lang.Integer
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
第一路:
fun Int?.orDefault(value: Int) = this ?: value
fun Double?.orDefault(value: Double) = this ?: value
// do the same for Float, Long, Char, Short and Byte
这将产生理想的行为
val default : Int = -1
val orDefault = b.orDefault(default.toDouble())
注意:您需要将default
转换为Double
,因为接收器是Double
,它需要一个Double
作为默认值
输出:
-1.0双重的 第二条道路 如果要接受任何
编号
,并将其转换为接收器类型,请执行以下操作:
fun Int?.orDefault(value: Number) = this ?: value.toInt()
fun Double?.orDefault(value: Number) = this ?: value.toDouble()
// do the same for Float, Long, Char, Short and Byte
最后,我做了这样的事情:
// Output:
-1
java.lang.Integer
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
fun <T : Number, J : Number> T?.orDefault(value: J): T = this ?: (value as T)
fun T?.orDefault(值:J):T=this?:(值为T)
这在不重写所有数字类型的情况下工作,并返回正确的类型
唯一的问题是它可以接受数字类型中的任何默认值。与Int一样,它可以接受双精度值作为默认值,并返回其Int表示形式。这很遗憾(