【发布时间】:2020-12-29 08:06:25
【问题描述】:
我想编写一个适用于任意类型的通用 Kotlin 函数,只要它们支持一些基本的数字运算,例如比较和加法。像这样的东西(注意:这段代码不能编译):
fun <T : ???> twiceTheLarger(a: T, b: T) = if (a > b) a + a else b + b;
在 C++ 中,这种代码可以工作。以下 C++ twiceTheLarger 函数采用支持 + 和 > 运算符的任何内容,无论是原始数字类型还是自定义类:
#include <iostream>
template <typename T> T twiceTheLarger(T a, T b) {
return a > b ? a + a : b + b;
}
int main() {
std::cout << twiceTheLarger(1, 2) << std::endl; // int values
std::cout << twiceTheLarger(42.0, 1.0) << std::endl; // double values
}
如何在 Kotlin 中获得类似的结果?到目前为止,我能想到的最好方法是显式传递具有所需功能的对象,如下所示:
interface NumericOperators<T> {
fun plus(a: T, b: T): T
fun greaterThan(a: T, b: T): Boolean
}
object IntNumericOperators : NumericOperators<Int> {
override fun plus(a: Int, b: Int) = a + b
override fun greaterThan(a: Int, b: Int) = a > b
}
object DoubleNumericOperators : NumericOperators<Double> {
override fun plus(a: Double, b: Double) = a + b
override fun greaterThan(a: Double, b: Double) = a > b
}
fun <T> twiceTheLarger(a: T, b: T, operators: NumericOperators<T>) =
if (operators.greaterThan(a, b)) operators.plus(a, a) else operators.plus(b, b)
fun main() {
println(twiceTheLarger(1, 2, IntNumericOperators)) // int values
println(twiceTheLarger(42.0, 1.0, DoubleNumericOperators)) // double values
}
有没有更好的办法?
编辑:
我意识到我可以为每个原始数字类型创建重载。问题是我正在编写一个库函数,它需要使用 arbitrary 类数字类型,甚至是我的库不知道的类型。因此,特定类型的重载不是一种选择。
【问题讨论】: