Kotlin中所需的运算符关键字是什么时候?
在第14次操作符重载的Kotlin Koan中 ,我惊讶地发现解决方案后,我看到了答案,并且看到compareTo
方法不需要operator
修饰符:
data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable { override fun compareTo(other: MyDate) = when { year != other.year -> year - other.year month != other.month -> month - other.month else -> dayOfMonth - other.dayOfMonth } }
运营商重载的文档中明确指出:
超载操作符需要用运算符修饰符标记。
那么这里发生了什么? 为什么这个代码编译? 何时需要operator
?
为什么这个代码编译?
这个编译是因为重写的接口方法Comparable
是一个operator fun
。
/** * Compares this object with the specified object for order. Returns zero if this object is equal * to the specified [other] object, a negative number if it's less than [other], or a positive number * if it's greater than [other]. */ public operator fun compareTo(other: T): Int
由于函数覆盖了这个,所以它也是一个运算符函数。
何时需要
operator
?
一般来说,只要你希望能够像使用操作符一样使用函数,就需要操作符,因为操作符的用法只是编译成函数调用(除了基本types等)
也就是说, foo += bar
等同于foo.plusAssign(bar)
, foo[bar] = baz
相当于foo.set(bar, baz)
等。
就我个人而言,为了可读性的原因,我希望尽可能地指定operator
即使不是必需的。
如果MyDate
不是 Comparable
,并且省略了operator
修饰符,则通过<
, >
, <=
或>=
比较两个日期将不会被编译。
虽然在规范中我找不到任何东西。 然而,从多态的角度来说,这是有道理的 - 为什么你应该能够写a < b
,其中a
和b
的types是Comparable
,而不是当它们是MyDate
? 既然你不能删除这个函数的“运算符”,那么operator
应该是可以从超类方法inheritance的。
Kotlin具有许多通过特定惯例启用的function。 这些可以通过使用operator
关键字来识别。 范例是范围 , 操作符重载, 索引操作符 , 解构声明等等。
如果我们想在Java中比较两个对象,例如,我们使用它的compareTo
方法来实现Comparable
接口。 这也是在Kotlin中完成的,但具有更好的支持和简短的语法。 如果你在一个类中实现了这个方法,那么你可以使用<
, <=
, >
, >=
等所有不错的运算符。 这些运算符被编译器翻译为适当的compareTo
调用:
obj1 > obj2
obj1.compareTo(obj2) > 0
compareTo
中的接口方法compareTo
已经定义了operator
关键字,这使得在您自己的实现中添加关键字成为多余的。
在你的例子中, operator
关键字不是强制的,因为重写的方法已经定义了它。