#operator #operator-overloading #sugar #concise #intuitive #i32 #left

无std operator-sugar

使Rust中的运算符重载更加简洁直观

3个版本

0.1.2 2019年8月12日
0.1.1 2019年8月12日
0.1.0 2019年8月10日

#334 in 无标准库

Apache-2.0

16KB
199

operator-sugar

使Rust中的运算符重载更加简洁直观。

详情请参阅文档


lib.rs:

此crate提供简单的宏,作为语法糖,使Rust中重载运算符更加容易。

二元运算符的基本语法格式如下

struct Left(i32);
struct Right(i32);
struct Answer(i32);

operator!(Left, Right: a + b -> Answer {
    // Implementation of the operator function here
    Answer(a.0 + b.0)
});

一元运算符

struct Operand(i32);
struct Answer(i32);

operator!(Operand: -a -> Answer {
    Answer(-a.0)
});

元属性

属性可以应用于impl块(例如实现Add)和相应的fn块。

struct Left(i32);
struct Right(i32);
struct Answer(i32);

operator!(
    #[doc("This attribute will be applied on the `impl` block")] Left, Right:
    #[doc("This attribute will be applied on the `fn` block")] a + b -> Answer {
        Answer(a.0 + b.0)
    });

泛型

泛型可以用于三种类型和impl块。

由于歧义消除,impl块的泛型参数必须用{}括起来,而不是<>

use core::ops::Add;
struct Left<T>(T) where T: Add<i32, Output = i32>;
struct Right(i32);
struct Answer(i32);

operator!(
    {T: Add<i32, Output = i32>}
    Left<T>, Right: a + b -> Answer {
        Answer(a.0 + b.0)
    });

运算符列表

为了简洁,以下示例中的每个定义都是针对以下示例的

use operator_sugar::*;
#[derive(Debug)] struct Left(i32);
#[derive(Debug)] struct Right(i32);
#[derive(Debug, Eq, PartialEq)] struct Answer(i32);

加法

#
operator!(Left, Right: a + b -> Answer {
    Answer(a.0 + b.0)
});

fn main() {
    assert_eq!(Left(1) + Right(2), Answer(3));
}

减法

#
operator!(Left, Right: a - b -> Answer {
    Answer(a.0 - b.0)
});

fn main() {
    assert_eq!(Left(1) - Right(2), Answer(-1));
}

乘法

#
operator!(Left, Right: a * b -> Answer {
    Answer(a.0 * b.0)
});

fn main() {
    assert_eq!(Left(3) * Right(2), Answer(6));
}

除法

#
operator!(Left, Right: a / b -> Answer {
    Answer(a.0 / b.0)
});

fn main() {
    assert_eq!(Left(8) / Right(2), Answer(4));
}

余数

#
operator!(Left, Right: a % b -> Answer {
    Answer(a.0 % b.0)
});

fn main() {
    assert_eq!(Left(9) % Right(5), Answer(4));
}

按位与

#
operator!(Left, Right: a & b -> Answer {
    Answer(a.0 & b.0)
});

fn main() {
    assert_eq!(Left(5) & Right(6), Answer(4));
}

按位或

#
operator!(Left, Right: a | b -> Answer {
    Answer(a.0 | b.0)
});

fn main() {
    assert_eq!(Left(5) | Right(6), Answer(7));
}

按位异或

#
operator!(Left, Right: a ^ b -> Answer {
    Answer(a.0 ^ b.0)
});

fn main() {
    assert_eq!(Left(5) ^ Right(6), Answer(3));
}

左移

#
operator!(Left, Right: a << b -> Answer {
    Answer(a.0 << b.0)
});

fn main() {
    assert_eq!(Left(5) << Right(3), Answer(40));
}

右移

#
operator!(Left, Right: a >> b -> Answer {
    Answer(a.0 >> b.0)
});

fn main() {
    assert_eq!(Left(43) >> Right(3), Answer(5));
}

索引

#[derive(Debug)] struct Left(Vec<i32>);
#[derive(Debug)] struct Right(usize);

operator!(Left, Right: a[b] -> &i32 {
    // The & is required to remind developers that a reference is to be returned.
    &a.0[b.0]
});

fn main() {
    // We check for 6 not &6, because while the impl returns &6, the [] operator from Rust dereferences it.
    assert_eq!(Left(vec![5, 6, 7])[Right(1)], 6);
}

负号(-


operator!(Left: -a -> Answer {
    Answer(-a.0)
});

fn main() {
    assert_eq!(-Left(43), Answer(-43));
}

非(!


operator!(Left: !a -> Answer {
    Answer(!a.0)
});

fn main() {
    assert_eq!(!Left(43), Answer(!43));
}

无运行时依赖