kotlin - 所有类似数字的值的通用函数?
问题描述
我想编写一个适用于任意类型的通用 Kotlin 函数,只要它们支持一些基本的数字运算,例如比较和加法。像这样的东西(注意:此代码无法编译):
fun <T : ???> twiceTheLarger(a: T, b: T) = if (a > b) a + a else b + b;
在 C++ 中,这种代码有效。以下 C++twiceTheLarger
函数采用支持+
and>
运算符的任何内容,无论是原始数字类型还是自定义类:
#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
}
有没有更好的办法?
编辑:
我意识到我可以为每个原始数字类型创建重载。问题是我正在编写一个库函数,它需要使用任意类似数字的类型,即使是我的库不知道的类型。因此,特定类型的重载不是一种选择。
解决方案
您将需要为每个原始类型创建函数。您不能使用<T : Number>
,尽管 Kotlin 中的所有数字都继承了这一点。Number
超类仅用于铸件。
您需要创建函数或扩展函数:
fun Int.twiceTheLarger(a: Int, b: Int) = if (a > b) a + a else b + b;
fun Double.twiceTheLarger(a: Double, b: Double) = if (a > b) a + a else b + b;
Comparable<T>
如果您可以在另一个函数中进行比较,那就太好了。T
需要超载的类型operator fun plus(other: T)
也是如此。
interface Addable<T>: Comparable<T>{
operator fun <T> Addable<T>.plus(a: T)
}
fun <T : Addable<T>> T.twiceTheLarger(a: T, b: T) {
return if (a > b) a.plus(a) else b + b
}
推荐阅读
- java - 无法将 Junit 添加到我的 Maven 项目(Netbeans)
- html - 为什么颜色不会变回黑色?
- kubernetes - 如何保持 kubernetes pod 的状态相同或自动恢复
- bash - 从另一个文件 sh 赋值
- javascript - 电子:按住元键的同时拖动范围控制
- .net-core - dotnet blazor Web 程序集模板 - 它在哪里?
- react-native - React Native Firebase - 即使我已经更新了 Firebase 模块的版本,我仍然遇到版本不匹配错误
- python - 从(x,y)坐标列表中如何找到角度变化的点?
- python - 注册和登录 api 中的 Django 休息框架
- arrays - 如何将十六进制值的字符串数组转换为vb.net中的字节数组