Kotlin函数语法

时间:2017-09-04 10:09:31

标签: kotlin

我正在进行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关键字中,我收到错误:

  

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

在我得到的回报中

  

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

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

3 个答案:

答案 0 :(得分:2)

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

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

  

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

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

  

具有块体的函数必须始终明确指定返回类型,除非它们旨在让它们返回Unit in which case it is optional。 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

答案 1 :(得分: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 或其他适用的类型)

答案 2 :(得分:0)

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

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