3个版本
0.1.2 | 2019年8月12日 |
---|---|
0.1.1 | 2019年8月12日 |
0.1.0 | 2019年8月10日 |
#334 in 无标准库
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));
}