首页 文章

Kotlin函数语法

提问于
浏览
0

我正在做Kotlin Koans测试,以便熟悉Kotlin . 在某个测试中,我必须覆盖 compareTo 方法 . 在第一种情况下,一切都按预期工作

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) {

    operator fun compareTo(other: MyDate)= when {
        year != other.year -> year - other.year
        month != other.month -> month - other.month
        else -> dayOfMonth - other.dayOfMonth
    }

}

现在,在第二种情况下,我正在以稍微不同的方式编写 compareTo ,我得到了大量的编译错误 .

data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) {


     operator fun compareTo(other: MyDate){

        when {
            year != other.year -> return year - other.year
            month != other.month -> return month - other.month
            else -> return dayOfMonth - other.dayOfMonth
       }
     }


 }

首先,在operator关键字中,我收到一个错误:

'operator'修饰符不适用于此函数:必须返回Int

在我得到的回报中

类型不匹配:推断类型为Int但预期为Unit

我无法理解为什么会出现这些错误,因为第一个实现返回相同的 Int

3 回答

  • 1

    那是因为 = 的工作原理为 { return X } 这仅适用于函数定义 . 所以这意味着在第一个例子中你的代码就是这个

    operator fun compareTo(other: MyDate):Int {
        return when {
            year != other.year -> year - other.year
            month != other.month -> month - other.month
            else -> dayOfMonth - other.dayOfMonth
        }
    }
    

    但是在你的第二个例子中,你没有返回 when 的结果 . 这会导致编译器混淆,因为它希望您返回 Int 但是返回 Unit (相当于Java的 void

    所以你需要做的就是为它添加一个显式的返回类型(在这种情况下为 Int )( fun X(/*args*/) : Int 或其他适用的类型)

  • 0

    在第一个示例中, compareTo(MyDate) 的返回类型为inferredInt ,因为 when 表达式的所有分支都返回 Int .

    在第二个示例中, compareTo(MyDate) 的返回类型是 Unit . 由于您的函数具有块体,因此必须明确指定返回类型(除非它们旨在让它们返回 Unit ) . 因此,对于返回类型,此处需要 Unit ,但从 when 表达式推断的返回类型为 Int . 这就是你得到错误的原因:

    类型不匹配:推断类型为Int但预期为Unit

    这是official explanation用于使用块体显式定义函数的返回类型:

    具有块体的函数必须始终明确指定返回类型,除非它们用于返回Unit,在这种情况下它是可选的 . Kotlin没有推断具有块体的函数的返回类型,因为这些函数在体内可能具有复杂的控制流,并且返回类型对于读者来说是不明显的(有时甚至对于编译器也是如此) .

    因此,声明 compareTo(MyDate) 的正确方法是指定函数的返回类型(如果它包含块体):

    operator fun compareTo(other: MyDate): Int {
        when {
            year != other.year -> return year - other.year
            month != other.month -> return month - other.month
            else -> return dayOfMonth - other.dayOfMonth
        }
    }
    

    这解决了另一个错误,因为comparison operator需要返回 Int .

  • 2

    只是对@Mibac答案的补充:你可以把它缩短一点:

    operator fun compareTo(other: MyDate) = when {
        year != other.year -> year - other.year
        month != other.month -> month - other.month
        else -> dayOfMonth - other.dayOfMonth
    }
    

相关问题