我做了一个简单的函数sqr,但它不起作用,怎么了?
fun <T : Number> sqr(value: T): T {
return value * value
}
fun main() {
print("${sqr(5)}")
}
Number
是对Double
、Int
等的抽象,但它不包括任何常见行为。相反,它包含了在不同具体类型之间进行转换的功能。
请参阅此处的源代码(或按IDE中的"转到实现"(
你必须将它们转换为一个具体的子类才能编译:
fun <T : Number> sqr(value: T): T {
return value.toInt() * value.toInt()
}
Number
没有times
函数(*
运算符转换为(。
Number
只是Int
、Float
、Double
等的抽象超类,只包含抽象转换函数:toInt()
、toFloat()
、toDouble()
等。
那么,如何绕过这一点,并为所有这些设置sqrt
函数呢?
由于它们没有包含基本操作的超类型,因此最好的想法是为每个类型单独实现,而不使用泛型类型。
fun sqr(value: Int) = value * value
fun sqr(value: Float) = value * value
fun sqr(value: Double) = value * value
// ...
或者,您可以在Number上使用运算符扩展,利用kotlin智能广播;可能看起来像这样:
operator fun Number.times(value: Number): Number {
return when(this) {
is Int -> this * value.toInt()
is Double -> this * value.toDouble()
is Short -> this * value.toShort()
is Float -> this * value.toFloat()
else -> throw IllegalArgumentException("Value is not a number")
}
}
所以你的平方函数是:
fun sqr(value: Number): Number {
return value * value
}
我想这里的好处是,您只维护1个平方函数,以及一个具有许多事例的运算符,这些事例代表您希望支持的具体数字类。