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
并在我得到的回报
types不匹配:推断types是Int,但Unit是预期的
我不明白为什么这些错误发生,因为第一个实现返回相同的Int
这是因为=
作为{ 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
)
所以你所要做的就是向它添加一个明确的返回types( fun X(/*args*/)
: Int
或其他适用的types)
在第一个示例中, compareTo(MyDate)
的返回types被推断为Int
因为when
expression式的所有分支都返回一个Int
。
在你的第二个例子中, compareTo(MyDate)
的返回types是Unit
。 由于你的函数具有块体,所以返回types必须明确指定(除非它们打算让它们返回Unit
)。 所以, Unit
在这里应该是返回types,但是when
你的expression式是Int
when
,返回types是可以被推断出来的。 这就是为什么你会得到这个错误:
types不匹配:推断types是Int,但Unit是预期的
下面是用块体明确定义函数的返回types的官方解释 :
块体的函数必须总是明确地指定返回types,除非它们打算让它们返回Unit, 在这种情况下它是可选的 。 Kotlin不推断块体的函数返回types,因为这样的函数可能在主体中有复杂的控制流,返回types对读者(有时甚至是编译器)也是不明显的。
因此,声明compareTo(MyDate)
的正确方法是指定函数的返回types(如果它包含块体):
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 } }
由于比较运算符需要返回一个Int
,所以同时解决了另一个错误。
除了@Mibac的答案:你可以缩短一点:
operator fun compareTo(other: MyDate) = when { year != other.year -> year - other.year month != other.month -> month - other.month else -> dayOfMonth - other.dayOfMonth }