【问题标题】:enum compareTo operator overloading with nullable value具有可为空值的枚举 compareTo 运算符重载
【发布时间】:2018-11-24 08:55:58
【问题描述】:

我在 Kotlin 中定义了一个枚举 SupportUsLevel。它的原始类型是字符串(出于其他原因),但我将numeric 值作为Int 包含在内以方便比较。我想将此枚举与另一个枚举进行比较,但这个也可以为空。所以我实现了一个 compareTo 运算符,它接受一个可为空的other

enum class SupportUsLevel(val value: String) {

    red("red"),
    blue("blue"),
    black("black");

    val numeric: Int
        get() {
            when (this) {
                red -> return 1
                blue -> return 5
                black -> return 7
            }
        }

    //return 0 if equal, negative (-1) is smaller, positive(+1) is bigger
    operator fun SupportUsLevel.compareTo(other: SupportUsLevel?) : Int {
        //if other is null, since I cannot be null, I am always bigger
        if (other == null) {
            return 1
        }
        //return numeric comparison since we both now have a value (due to null-check before)
        return numeric.compareTo(other.numeric)
       }
}

但是,当我想使用它时,编译器无法识别此自定义比较?我得到一个类型不匹配:

【问题讨论】:

  • 枚举具有内在的自然顺序,即它们的顺序,即它们被声明的顺序。你不能覆盖它。 docs.oracle.com/javase/8/docs/api/java/lang/…
  • 但是序数是一个字符串?或者你的意思是他们声明的顺序?所以重载一个运算符来与一个可以为空的比较是不可能的?
  • 序号是枚举常量在声明中的位置。 0 代表红色,1 代表蓝色,2 代表黑色。 docs.oracle.com/javase/8/docs/api/java/lang/Enum.html#ordinal--
  • 好的,谢谢你的信息。但是实现一个可以为空的自定义 compareTo 是不可能的?
  • 实例方法总是优于扩展函数。

标签: kotlin


【解决方案1】:

实例方法总是优于扩展(请参阅 org 问题中 JB Nizet 的 cmets),这意味着编译器永远不会识别自定义的 compareTo。

我能找到的最佳解决方案是使其成为标准成员函数 (注意它不再是比较,而是isHigherThen(...),因为这是我需要的):

enum class SupportUsLevel(val value: String) {

    //since we are using the standard enum compare operator the order must be low to high!
    //refer to https://stackoverflow.com/questions/53456649/enum-compareto-operator-overloading-with-nullable-value

    red("red"),
    blue("blue"),
    black("black");

    val numeric: Int
        get() {
            when (this) {
                red -> return 1
                blue -> return 5
                black -> return 7
            }
        }

    fun isHigherThen(other: SupportUsLevel?) : Boolean {
        //if other is null, since I cannot be null, I am always bigger
        if (other == null) { return true }
        //return numeric comparison since we both now have a value (due to null-check before)
        return numeric > other.numeric
    }
}

【讨论】:

    猜你喜欢
    • 2011-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    相关资源
    最近更新 更多