操作符重载

Operator overloading is a feature in some programming languages that allows the redefinition of standard operators, such as addition (+), subtraction (-), multiplication (*), and division (/), to work with user-defined types. This can make the syntax of the code more intuitive, by enabling operations on user-defined types to be expressed in the same way as operations on primitive types.

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.

让我看一个例子,两个 Potions 需要合并。Potions 有两个数据字段,法力(mana)和健康(health)。合并两个Potions 应该是让它们各自的两个字段相加。

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, '');
}

在上面的代码中,我们为 Potion类型实现Add特性。Add函数需要两个参数:lhsrhs(左手端和右手端,分别表示在运算式的左边还是右边)。函数主体返回一个新的Potion实例,其字段值是lhsrhs的组合。

正如例子中所说明的,重载一个操作符需要指定被重载的具体类型。这里被重载用泛型表示的trait是 Add<Potion>,所以我们将用 Add<Potion>为 ‘Potion`类型定义一个具体的实现。