repo: symm_impl
之前看到社区里的一个帖提问如何实现两个不同类型的对称操作,比如圆和矩形是否相交(即圆和矩形是否相交等价于矩形和园是否相交)。由于我是做计算几何的,想到确实几何种这种算符很多,比如距离算符,集合交并算符,都满足不同类型实现对称运算符的问题。
于是就花了点时间写了个attribute macro,用于在实现了一边的情况下,自动实现对称的版本。
以点和圆的距离作为例子
use symm_impl::symmetric;
trait Distance<Other> {
fn distance(&self, other: &Other) -> f64;
}
struct Point2D {
x: f64,
y: f64,
}
struct Disk {
center: Point2D,
radius: f64
}
impl Distance<Point2D> for Point2D {
fn distance(&self, other: &Point2D) -> f64 {
let dx = self.x - other.x;
let dy = self.y - other.y;
(dx * dx + dy * dy).sqrt()
}
}
#[symmetric]
impl Distance<Disk> for Point2D {
fn distance(&self, other: &Disk) -> f64 {
let p_diff = self.distance(&other.center);
if p_diff.le(&other.radius) {
0.0_f64
} else {
p_diff - other.radius
}
}
}
/* Expands to
impl Distance<Point2D> for Disk {
#[allow(unused_mut)]
#[inline]
fn distance(&self, other: &Point2D) -> f64 {
<Point2D as Distance>::distance(other, self)
}
}
*/
fn main() {
let p = Point2D { x: 5.0, y: 4.0 };
let c = Disk {
center: Point2D { x: 1.0, y: -2.0 },
radius: 3.0,
};
assert_eq!(p.distance(&c), c.distance(&p));
}
Ext Link: https://github.com/johnmave126/symm_impl
1
共 1 条评论, 1 页
评论区
写评论star了。有点意思啊,其实rust官方真该出一个类似的宏作为语法糖进标准库,因为实际上很多操作普遍满足交换律。