Operator Overloading

La sobrecarga de operadores es una característica de algunos lenguajes de programación que permite redefinir operadores estándar, como la suma (+), la resta (-), la multiplicación (*) y la división (/), para que funcionen con tipos definidos por el usuario. Esto puede hacer que la sintaxis del código sea más intuitiva, al permitir que las operaciones sobre tipos definidos por el usuario se expresen del mismo modo que las operaciones sobre tipos primitivos.

In Cairo, operator overloading is achieved through the implementation of specific traits. Each operator has an associated trait, and overloading that operator involves providing an implementation of that trait for a custom type. However, it's essential to use operator overloading judiciously. Misuse can lead to confusion, making the code more difficult to maintain, for example when there is no semantic meaning to the operator being overloaded.

Consideremos un ejemplo en el que hay que combinar dos Potions. Las Potions tienen dos campos de datos, maná y salud. Al combinar dos Potions se deben añadir sus respectivos campos.

struct Potion {
    health: felt252,
    mana: felt252
}

impl PotionAdd of Add<Potion> {
    fn add(lhs: Potion, rhs: Potion) -> Potion {
        Potion { health: lhs.health + rhs.health, mana: lhs.mana + rhs.mana, }
    }
}

fn main() {
    let health_potion: Potion = Potion { health: 100, mana: 0 };
    let mana_potion: Potion = Potion { health: 0, mana: 100 };
    let super_potion: Potion = health_potion + mana_potion;
    // Both potions were combined with the `+` operator.
    assert(super_potion.health == 100, '');
    assert(super_potion.mana == 100, '');
}

En el código anterior, estamos implementando el rasgo Add para el tipo Potion. La función add toma dos argumentos: lhs y rhs (izquierda y derecha). El cuerpo de la función devuelve una nueva instancia de Poción, cuyos valores de campo son una combinación de lhs y rhs.

Como se ilustra en el ejemplo, la sobrecarga de un operador requiere la especificación del tipo concreto que se sobrecarga. El trait genérico sobrecargado es Add<T>, y definimos una implementación concreta para el tipo Potion con Add<Potion>.

Last change: 2023-09-20, commit: cbb0049