【发布时间】:2020-03-21 19:29:46
【问题描述】:
以下函数可以编译,但只能与 Doubles 一起使用:
fun triang(x: Double): Double {
var m = x - truncate(x)
if (m < 0) m += 1.0
return when {
m < 0.25 -> 4.0 * m
m < 0.50 -> 2.0 - 4.0 * m
m < 0.75 -> 2.0 - 4.0 * m
else -> 4.0 * m - 4.0
}
}
我也希望能够将该函数与 Floats 一起使用,因此我尝试将其设为通用函数:
fun <T: Number> triang(x: T): T {
var m = x.toDouble() - truncate(x.toDouble())
if (m < 0) m += 1.0
return when {
m < 0.25 -> 4.0 * m
m < 0.50 -> 2.0 - 4.0 * m
m < 0.75 -> 2.0 - 4.0 * m
else -> 4.0 * m - 4.0
} as T // problem here
}
但这不起作用,因为转换为 T 会导致警告“未经检查的转换:双倍转换为 T”。
如何正确地为 Float 和 Double 编写通用函数?
【问题讨论】:
-
一种方法是通过重载
fun triang(x: Float) = triang(x.toDouble()).toFloat()。这正是您的通用实现要做的事情。我知道这不能回答你的问题。但它比泛型实现更安全,因为它不适用于其他Number类型。 -
是的,我最终可能会这样做。但我仍然对泛型是否可以做到这一点感兴趣。
-
不,因为没有办法将
Double转换回T(既不是你尝试的演员也不是方法);至少没有测试所有类型(如when(x) { is Double -> ...; is Float -> ...; ... }) -
你可以试试
inline fun <reified T : Number> ...,这会允许演员,但它总是会因为拳击而失败(Double除外)。
标签: generics kotlin generic-function