Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When exactly is the operator keyword required in Kotlin?

In the 14th Kotlin Koan on operator overloading, I was suprised when after solving I viewed the answer and saw that the operator modifier was not required on the compareTo method:

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     } } 

The operator overloading docs linked to from the exercise explicitly says:

Functions that overload operators need to be marked with the operator modifier.

So what's going on here? Why does this code compile? When exactly is operator required?

like image 417
Tom Tresansky Avatar asked Jan 10 '18 17:01

Tom Tresansky


People also ask

What is the use of the operator keyword in Kotlin?

Kotlin allows you to provide custom implementations for the predefined set of operators on types. These operators have predefined symbolic representation (like + or * ) and precedence. To implement an operator, provide a member function or an extension function with a specific name for the corresponding type.

What is the use of keyword operator?

The operator keyword declares a function specifying what operator-symbol means when applied to instances of a class. This gives the operator more than one meaning, or "overloads" it. The compiler distinguishes between the different meanings of an operator by examining the types of its operands.

Can you overload operators in Kotlin?

Since Kotlin provides user-defined types, it also provides the additional functionality to overload the standard operators, so that working with user-defined types is easier. All of the unary, binary, relational operators can be overloaded.

What is the name operator in Kotlin?

"Kotlin in Action" calls it the not-null assertion operator. We've decided to update the docs to use this term too. Show activity on this post. that is also how it is shown in the Android studio ALT + ENTER context menu.

What is the use of when keyword in Kotlin?

The kotlin when is one of the expression and used it on the conditional statements which has returned the value it has the replacement of the other feature called a switch statement. “when” keyword used normally it is not mandatory also the when the statement is used in the multiple branches of the condition.

How to turn a function into an operator in Kotlin?

In order to turn a Kotlin function with a pre-defined name into an operator, we should mark the function with the operator modifier. For example, we can overload the “+” operator: This does not even address the question, let alone answer it.

Is and as in Kotlin unsafe to use?

"Kotlin in action" by Dmitry Jemerov and Svetlana Isakova has a good example of as and is: val x: String = y as String val x: String? = y as String? val x: String? = y as? String Usually, the cast operator throws an exception if the cast is not possible. Thus, we call it unsafe. The unsafe cast in Kotlin is done by the infix operator as

How do you compare two objects in Kotlin?

Kotlin has many features that are enabled via particular conventions. Those can be identified by the use of an operator keyword. Examples are ranges, operator overloads, index operators, destructuring declarations and more. If we want to compare two objects in Java, for sorting e.g., we implement the Comparable interface with its compareTo method.


Video Answer


2 Answers

Why does this code compile?

This compiles because the overridden interface method, Comparable<T>.compareTo, is itself an 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 

As the function overrides this, it is also an operator function.

When exactly is operator required?

operator in general is required whenever you wish to be able to use a function as if it were an operator, since operator usages are simply compiled to function calls (except on primitive types, etc.)

That is, foo += bar, for example, is equivalent to foo.plusAssign(bar), foo[bar] = baz is equivalent to foo.set(bar, baz), etc.

Personally I prefer specifying operator wherever possible even if it is not required, for readability reasons.

If MyDate were not a Comparable, and you omitted the operator modifier, comparing two dates via <, >, <=, or >= would not compile.

I couldn't find anything in the specification on this, though. However in a polymorphic sense it makes sense - why should you be able to write a < b where the type of a and b are Comparables, but not when they are a MyDate? Since you wouldn't be able to remove the "operator-ness" of this function, it makes sense that operator should be inheritable from the superclass method.

like image 59
Salem Avatar answered Oct 20 '22 13:10

Salem


Kotlin has many features that are enabled via particular conventions. Those can be identified by the use of an operator keyword. Examples are ranges, operator overloads, index operators, destructuring declarations and more.

If we want to compare two objects in Java, for sorting e.g., we implement the Comparable interface with its compareTo method. This is also done in Kotlin, but with much better support and a shorthand syntax. If you implement this method in a class, you can use all the nice operators like <, <=, >, >= with that class out of the box. These operators are translated to appropriate calls of compareTo by the compiler:

obj1 > obj2obj1.compareTo(obj2) > 0

The interface method compareTo in Comparable already defines the operator keyword, which makes it redundant to add the keyword in your own implementation.

In your example, the operator keyword is not mandatory since the overridden method already defines it.

like image 23
s1m0nw1 Avatar answered Oct 20 '22 13:10

s1m0nw1