In Kotlin, il sovraccarico degli operatori (operator overloading) è supportato attraverso la parola chiave operator. Questo consente di definire la logica personalizzata per gli operatori standard (+, -, *, [], ==, ecc.) per i tipi utente:
operator.Esempio:
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 // chiamerà la funzione operator fun plus
Nuanze e best practice:
== e equals dovrebbero essere coerenti).Qual è la differenza tra il sovraccarico dell'operatore
==e l'override del metodoequals()?
Risposta: L'operatore == in Kotlin chiama sempre il metodo equals() (con un controllo preliminare per null). Se definisci la funzione operator fun equals(other: Any?): Boolean, l'operatore == utilizzerà sempre questo metodo. Non è possibile far sì che == e equals() funzionino in modo diverso.
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) // chiamerà a.equals(b)
Storia
Sovraccaricato l'operatore compareTo senza una semantica chiara:
Nella classe Point è stata definita operator fun compareTo per poterla utilizzare negli ordinamenti. Tuttavia, "più grande" e "più piccolo" non avevano un significato chiaro, i vari membri del team scrivevano logiche diverse. Risultato: bug confusi durante l'ordinamento delle raccolte.
Storia
Dimenticato il principio di simmetria degli operatori per tipi reciproci:
Un sviluppatore ha implementato operator fun plus(a: Matrix, b: Vector): Matrix, ma non ha garantito il funzionamento per Vector + Matrix, poiché non ha implementato la funzione simmetrica.
Di conseguenza, l'espressione vector + matrix non si compilava, solo matrix + vector funzionava. Questo ha causato bug in molte parti del codice.
Storia
Sovraccarico errato dell'operatore get:
Uno sviluppatore ha creato una classe personalizzata sovraccaricando operator fun get(index: Int): Foo. Non ha aggiunto verifiche per l'uscita dai limiti e il tentativo di accedere a un elemento non esistente restituiva un oggetto con campi non validi, invece di lanciare un'eccezione, il che ha portato alla comparsa di errori "invisibili" nella logica aziendale.