Comparable 和运算符 compareTo 有什么区别?

What is the difference between Comparable and operator compareTo?

假设我有 class A(val foo: Double).

我希望能够将它与其他 ADoubleInt 进行比较。

如果我实施 Comparable,我只能将它与另一种对象类型进行比较。

override fun compareTo(other: A): Int {
        return when {
            this.foo == other.foo -> 0
            this.foo > other.foo -> 1
            else -> -1
        }
    }

但我也看到了覆盖 compareTo 运算符的扩展函数。

operator fun A.compareTo(d: Double): Int {
    return when {
        this.foo == d -> 0
        this.foo > d -> 1
        else -> -1
    }
}

这些有什么区别,我应该使用什么?我猜如果我想将它与多种类型进行比较,那么我必须使用扩展函数吗?

Comparable 接口来自 Java,如您所见,它仅使用 compareTo(other) 方法定义,该方法仅提供将一个对象与另一个相同类型的对象进行比较。

正如您还注意到的,Kotlin 扩展函数是附加函数,允许您将对象与您想要的任何对象进行比较,只要您定义 compareTo 方法以获取要比较的类型的参数.

所以,是的,如果您想将一个对象与不同类型的对象进行比较,您将需要编写适当的扩展函数。

当然,在 Java 中,如果您可以控制 class 的源代码,您可以随时添加自定义 compareTo 方法。

如果你创建自己的对象,你必须实现 Comparable 接口,然后覆盖 compareTo 函数

class MyClass : Comparable<MyClass> {

   override fun compareTo(other: MyClass): Int {
      // TODO Returns zero if this object is equal to the specified other object
   }

}

你也可以覆盖一个运算符函数,例如来自 Int class in kotlin

fun main(args: Array<String>) {
   val a = 1
   val b = "2"
   println(a.compareTo(b))
}

operator fun Int.compareTo(i: String) : Int {
   return if (this.toString() == i) {
      0
   } else {
      1
   }
}

希望对你有所帮助

Comparable 是一个标准接口,它是您将 class 定义为具有某种排序的方式,并且每个处理排序的库都使用 Comparable 类型。基本上,如果您希望能够使用所有标准函数和任何其他人可能编写的东西来订购和比较您的东西,您需要实现 Comparable 接口。

这个有效:

data class SportsTeam(val name: String) : Comparable<SportsTeam> {
    override fun compareTo(other: SportsTeam): Int = when {
        name == "best team" -> 1
        other.name == "best team" -> -1
        else -> 0
    }
}

fun main(args: Array<String>) {
    val best = SportsTeam("best team")
    val worst = SportsTeam("worst team")
    print("The winner is: ${maxOf(best, worst).name}")
}

但是因为 maxOf 采用 Comparable 类型,所以这行不通:

data class SportsTeam(val name: String)

fun SportsTeam.compareTo(other: SportsTeam): Int = when {
    name == "best team" -> 1
    other.name == "best team" -> -1
    else -> 0
}

fun main(args: Array<String>) {
    val best = SportsTeam("best team")
    val worst = SportsTeam("worst team")
    print("The winner is: ${maxOf(best, worst).name}")
}