Swift accorde traditionnellement une grande importance à la pureté de la syntaxe et permet de créer ses propres opérateurs (surcharge d'opérateurs), y compris de nouveaux symboles et même des mots-clés. Cela élargit les possibilités de DSL et permet de rendre le code très expressif.
Sans comprendre les principes de déclaration des opérateurs, il est possible d'obtenir un code ambigu, difficile à lire et à maintenir. Un choix incorrect de la priorité ou de l'associativité conduira à des résultats inattendus. Le compilateur permet de créer des expressions assez "dangereuses" s'il n'y a pas de restrictions.
On peut déclarer de nouveaux opérateurs infix, prefix, postfix, spécifier leurs priorités et domaines d'application. Exemple :
infix operator ~> : AdditionPrecedence func ~> (lhs: Int, rhs: Int) -> Int { return lhs * 10 + rhs } let x = 2 ~> 3 // 23
Pour des priorités personnalisées, il faut déclarer :
precedencegroup MyPrecedence { associativity: left higherThan: AdditionPrecedence } infix operator *** : MyPrecedence
Caractéristiques clés :
Est-il obligatoire d'implémenter à la fois la fonction et la déclaration de l'opérateur ?
Oui, si vous déclarez un opérateur, il faut implémenter la fonction correspondante, sinon cela entraînera une erreur de compilation. Les fonctions ont une signature qui correspond à l'opérateur par signature.
Comment choisir correctement un precedencegroup et comment les groupes influent-ils sur l'ordre de calcul ?
Le precedencegroup définit la priorité de calcul et l'associativité pour les opérateurs infix. Un choix incorrect du groupe peut entraîner des résultats inattendus dans les expressions avec plusieurs opérateurs (par exemple, multiplication/addition et votre opérateur personnalisé).
Peut-on déclarer un opérateur personnalisé avec un nom textuel ?
Non, les opérateurs personnalisés ne sont accessibles que par des symboles spéciaux ou des séquences définies par la syntaxe de Swift. Les noms textuels standards ne sont pas autorisés pour la déclaration en tant qu'opérateur.
Des opérateurs <<< et >>> ont été déclarés dans le projet pour de curieux transformations de collections, sans description de priorité, d'associativité et de documentation. Les nouveaux employés ne comprenaient pas ce qu'ils faisaient ni dans quel ordre les expressions étaient calculées.
Avantages :
Inconvénients :
Dans le projet, un opérateur personnalisé => a été utilisé pour une construction déclarative d'un pipeline chainable (par exemple, dans un constructeur UI), avec une priorité clairement décrite et une implémentation documentée. Chaque développeur comprenait ce qu'il faisait et comment cela était utilisé.
Avantages :
Inconvénients :