Operators
A short exposition of operators, and why they should be used sparingly. Special mentions of invoke, componentN, contains and rangeTo, and the index array access operator [].
— — — — — — — — — — — — — — —
THE CURRENT VERSION OF THIS ARTICLE IS PUBLISHED HERE.
— — — — — — — — — — — — — — —

Tags: #KOTLIN FEATURE
This article is part of the Kotlin Primer, an opinionated guide to the Kotlin language, which is indented to help facilitate Kotlin adoption inside Java-centric organizations. It was originally written as an organizational learning resource for Etnetera a.s. and I would like to express my sincere gratitude for their support.
It is recommended to read the Introduction before moving on. Check out the Table of Contents for all articles.
Unlike Java, Kotlin allows you to provide custom implementations for a predefined set of operators. Operators are ordinary methods that can be called using a special syntax, e.g. operator fun plus() can be called using +, == calls equals, > calls compareTo etc.
I would recommend you go easy on them. There are situations where implementing an operator makes clear sense (i.e. when creating a Vector2D class, plus makes perfect sense), but unless there is an absolutely crystal clear concept of what a given operator means in the domain you’re modeling, it’s usually best to avoid them.
For example, going back to Vector2D, plus might make sense, but what about times? There are two product operations associated with a vector, the dot and cross products. Which one should you implement? Probably neither, because there isn’t any general argument that makes one more important or fundamental than the other. But if you don’t implement either, does it make sense to implement plus and be inconsistent with which operations are implemented? It might be, but these are the kinds of questions you should ask yourself before going down this road. Often, it’s much better to simply define a custom infix function.
You can find the list of legal operators in the docs. The vast majority won’t surprise you, but there are a couple of operators I want to mention explicitly: invoke, componentN, contains and rangeTo, and the index array access operator [].
Invoke
The invoke operator is certainly among the less traditional operators, because it represents a function call. In actuality, f() calls f.invoke(), in the same way that 2 + 3 actually calls 2.plus(3). You can see this for yourself when you look at the definition of e.g. Function1 and its counterparts.
Therefore, any object can be called like a function just by implementing the invoke operator:

