En Kotlin, le surchargement d'opérateurs (operator overloading) est pris en charge par le mot-clé operator. Cela permet de définir sa propre logique pour le fonctionnement des opérateurs standards (+, -, *, [], ==, etc.) pour des types utilisateur :
operator.Exemple :
data class Vec2(val x: Int, val y: Int) { operator fun plus(other: Vec2) = Vec2(x + other.x, y + other.y) } val a = Vec2(1,2) val b = Vec2(2,3) val c = a + b // appellera operator fun plus
Nuances et meilleures pratiques :
== et equals doivent être cohérents).Quelle est la différence entre la surcharge de l'opérateur
==et la redéfinition de la méthodeequals()?
Réponse : L'opérateur == en Kotlin appelle toujours la méthode equals() (avec une vérification préalable pour null). Si vous définissez operator fun equals(other: Any?): Boolean, l'opérateur == utilisera toujours cette méthode. Il n'est pas possible de faire en sorte que == et equals() fonctionnent de manière différente.
data class Point(val x: Int, val y: Int) { override operator fun equals(other: Any?): Boolean { ... } } val a = Point(1,2) val b = Point(1,2) println(a == b) // appellera a.equals(b)
Histoire
Surcharge de l'opérateur compareTo sans sémantique explicite :
Dans la classe Point, operator fun compareTo a été définie pour permettre son utilisation dans les tris. Cependant, "plus grand" et "plus petit" n'avaient pas de sens explicite, différents membres de l'équipe ont écrit une logique différente. Résultat — des bugs confus lors du tri des collections.
Histoire
Oubli de la symétrie des opérateurs pour des types mutuels :
Le développeur a implémenté operator fun plus(a: Matrix, b: Vector): Matrix, mais n'a pas assuré le fonctionnement pour Vector + Matrix, car il n'a pas implémenté la fonction symétrique. Ainsi, l'expression vector + matrix ne compilait pas, seul matrix + vector fonctionnait. Cela a provoqué des bugs dans de nombreuses parties du code.
Histoire
Surcharge erronée de l'opérateur get :
Le développeur a créé une classe personnalisée, surchargeant operator fun get(index: Int): Foo. Il n'a pas ajouté de vérifications de dépassement des limites — et une tentative d'accès à un élément inexistant renvoyait un objet avec des champs non valides, au lieu de lancer une exception — ce qui a conduit à des erreurs "invisibles" dans la logique métier.