Swift tradizionalmente pone grande attenzione alla pulizia della sintassi e consente di creare operatori propri (operator overloading), inclusi nuovi simboli e persino parole chiave. Questo amplia le possibilità di DSL e permette di rendere il codice molto espressivo.
Senza una comprensione dei principi di dichiarazione degli operatori, si può ottenere un codice ambiguo, poco leggibile e difficile da mantenere. Una priorità o un'associatività scelte in modo errato porteranno a risultati inaspettati. Il compilatore consente di creare espressioni piuttosto "pericolose" se non si specificano limitazioni.
È possibile dichiarare nuovi operatori infix, prefix, postfix, specificare le loro priorità e ambiti di applicazione. Esempio:
infix operator ~> : AdditionPrecedence func ~> (lhs: Int, rhs: Int) -> Int { return lhs * 10 + rhs } let x = 2 ~> 3 // 23
Per priorità personalizzate è necessario dichiarare:
precedencegroup MyPrecedence { associativity: left higherThan: AdditionPrecedence } infix operator *** : MyPrecedence
Caratteristiche chiave:
È obbligatorio implementare sia la funzione che la dichiarazione dell'operatore?
Sì, se dichiari un operatore, devi implementare la funzione corrispondente, altrimenti ci sarà un errore di compilazione. Le funzioni hanno una firma che corrisponde all'operatore per firma.
Come scegliere correttamente precedencegroup e come influiscono i group sull'ordine di calcolo?
precedencegroup definisce la priorità di calcolo e l'associatività per gli operatori infix. Una scelta errata del group può portare a risultati inaspettati nelle espressioni con più operatori (ad esempio, moltiplicazione/addirittura e il tuo operatore personalizzato).
È possibile dichiarare un operatore personalizzato con un nome testuale?
No, gli operatori personalizzati sono disponibili solo attraverso simboli speciali o sequenze definite dalla sintassi Swift. I nomi standard testuali non sono consentiti per la dichiarazione come operatore.
Nel progetto sono stati dichiarati operatori <<< e >>> per strane trasformazioni delle collezioni, senza una descrizione di priorità, associatività e documentazione. I nuovi dipendenti non capivano cosa stessero facendo e in quale ordine venivano calcolate le espressioni.
Pro:
Contro:
Nel progetto è stato utilizzato l'operatore personalizzato => per costruire in modo dichiarativo una pipeline chainable (ad esempio, in un UI builder), con priorità chiaramente documentata e implementazione documentata. Ogni sviluppatore capiva cosa stesse facendo e come fosse utilizzato.
Pro:
Contro: