Generics 浮点和双精度的Kotlin通用函数

Generics 浮点和双精度的Kotlin通用函数,generics,kotlin,generic-function,Generics,Kotlin,Generic Function,以下函数可编译,但只能与double一起使用: 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

以下函数可编译,但只能与double一起使用:

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
    }
}
fun三角形(x:Double):Double{
var m=x-截断(x)
如果(m<0)m+=1.0
何时返回{
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
}
}
我希望能够将该函数与浮点一起使用,因此我尝试将其转换为通用函数:

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
}
fun三角形(x:T):T{
var m=x.toDouble()-truncate(x.toDouble())
如果(m<0)m+=1.0
何时返回{
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
}这里的问题是
}
但这不起作用,因为对t的强制转换会导致警告,“未经检查的强制转换:加倍到t”


如何正确地为Float和Double编写通用函数?

Kotlin不支持像Java这样的数字强制转换,并且没有明确的方法将数字转换为擦除的数字类型。对于双重和浮动,最好采用过载法


但是,您可以抑制此警告,因为实际上此代码将首先将返回值强制转换为数字,然后它将从中调用
value
,但这不是很好,因为此函数不是为整数值设计的,如果您调用
trianga(1)
,这将导致结果的精度损失。

Kotlin不支持对Java等数字进行强制转换,并且没有明确的方法将数字转换为已擦除的数字类型。对于双重和浮动,最好采用过载法


但是,您可以抑制此警告,因为实际上此代码将首先将返回值强制转换为数字,然后它将从中调用
value
,但这不是很好,因为此函数不是为整数值设计的,如果您调用
trianga(1)
,这将导致结果的精度损失。

一种方法是通过重载
有趣的三角形(x:Float)=三角形(x.toDouble()).toFloat()
。这正是您的通用实现所要做的。我知道这不能回答你的问题。但它比泛型实现更安全,因为它不适用于其他
Number
类型。但是我仍然感兴趣的是,是否可以用泛型来实现它。不,因为没有办法将一个
Double
转换回
T
(既不是您尝试的cast,也不是方法);至少在不测试所有类型的情况下(比如
当(x){is Double->…;is Float->…;…}
),您可以尝试
内联fun…
,这将允许强制转换,但由于装箱(除了
Double
)它总是会失败。一种方法是通过重载
fun triangal(x:Float)=trianga(x.toDouble()).toFloat()来实现
。这正是您的通用实现所要做的。我知道这不能回答你的问题。但它比泛型实现更安全,因为它不适用于其他
Number
类型。但是我仍然感兴趣的是,是否可以用泛型来实现它。不,因为没有办法将一个
Double
转换回
T
(既不是您尝试的cast,也不是方法);至少在不测试所有类型的情况下(比如当(x){is Double->…;is Float->…;…}),您可以尝试
inline fun…
,这将允许强制转换,但由于装箱(除了
Double
)而总是失败。