什么时候Kotlin需要运营商关键字?

时间:2018-01-10 17:59:21

标签: kotlin operator-overloading

14th Kotlin Koan on运算符重载时,我很惊讶,在解决后我查看了答案并发现operator修饰符 <{1}}方法:

compareTo

与练习相关联的operator overloading docs明确表示:

  

需要使用运算符标记重载运算符的函数   改性剂。

那么这里发生了什么?为什么这段代码会编译?何时需要data class MyDate(val year: Int, val month: Int, val dayOfMonth: Int) : Comparable<MyDate> { override fun compareTo(other: MyDate) = when { year != other.year -> year - other.year month != other.month -> month - other.month else -> dayOfMonth - other.dayOfMonth } }

2 个答案:

答案 0 :(得分:8)

  

为什么这段代码会编译?

这是编译,因为重写的界面方法Comparable<T>.compareTo 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

一般情况下,只要你希望能够使用函数就像运算符一样,

operator是必需的,因为运算符用法只是编译为函数调用(基本类型等除外)

也就是说,foo += bar相当于foo.plusAssign(bar)foo[bar] = baz相当于foo.set(bar, baz)等。

出于可读性原因,我个人更喜欢尽可能指定operator,即使不是必需的。

如果MyDate Comparable,您省略了operator修饰符,则通过<,{{1}比较两个日期},><=无法编译。

虽然我在specification找不到任何内容。然而,在多态意义上它是有道理的 - 为什么你应该能够写>= a < ba的类型为b,而不是当它们是ComparableMyDate?由于您无法删除此函数的“operator-ness”,因此operator应该可以从超类方法继承。

答案 1 :(得分:4)

Kotlin具有许多通过特定约定启用的功能。可以使用operator关键字来识别这些内容。示例包括范围运算符重载, 索引运算符解构声明等。

如果我们想比较Java中的两个对象,例如,我们使用Comparable方法实现compareTo接口。这也是在Kotlin中完成的,但有更好的支持和简写语法。如果在类中实现此方法,则可以使用开箱即用的所有类似<<=>>=等优秀运算符。这些运算符被编译器转换为compareTo的适当调用:

obj1 > obj2obj1.compareTo(obj2) > 0

The interface method compareTo in Comparable已经定义了operator关键字,这使得在您自己的实现中添加关键字变得多余。

在您的示例中,operator关键字不是必需的,因为重写的方法已经定义了它。