Generics 浮点和双精度的Kotlin通用函数
以下函数可编译,但只能与double一起使用: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
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
)而总是失败。