操作符重载

操作符重载是一些编程语言的一个特点,它允许在用户自定义的类型上重新定义标准操作符,如加法(+)、减法(-)、乘法(*)和除法(/)。这可以使代码的语法更加直观,因为它使对用户字定义类型的操作与对原始类型的操作表达方式相同。

在Cairo中,操作符重载是通过实现特定的trait来实现的。每个操作符都有一个相关的traits,操作符重载涉及到需为一个自定义类型提供该trait的实现。 然而,明智地使用操作符重载是非常重要的。误用会导致混乱,使代码更难维护,比如当被重载的操作符的语义与操作符原有的语义毫不相干的时候。

让我看一个例子,两个 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`类型定义一个具体的实现。

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