首页 > 解决方案 > 所有类似数字的值的通用函数?

问题描述

我想编写一个适用于任意类型的通用 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
}

有没有更好的办法?

编辑:

我意识到我可以为每个原始数字类型创建重载。问题是我正在编写一个库函数,它需要使用任意类似数字的类型,即使是我的库不知道的类型。因此,特定类型的重载不是一种选择。

标签: kotlingenerics

解决方案


您将需要为每个原始类型创建函数。您不能使用<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
    }

推荐阅读