< 返回版块

miaooo0000OOOO 发表于 2023-08-10 18:39

比如

// 需要实现交换律的trait
// 判断两个几何图形是否相交
pub trait Intersect<T> {
    fn intersect(&self, rhs:T)->bool;
}

// 实现判断射线与线段是否相交的代码
impl Intersect<&LineSegment> for HalfLine {
    fn intersect(&self, ls: &LineSegment) -> bool {
        todo!()
    }
}

// 实现判断线段与射线是否相交的代码
// 这一部分希望能自动实现
impl Intersect<&HalfLine> for LineSegment{
    fn intersect(&self, rhs:&HalfLine)->bool {
        rhs.intersect(self)
    }
}

评论区

写评论
ribs 2023-10-17 16:17

Intersect<T> 缺少约束,T代表任意类型,所以没办法impl<T, U> Intersect<U> for T,这里U也是T。 可以从现实出发,你的图像虽然是两个不同类型,但按理应该实现了某个Trait,这里假如是Area,那么就比较顺理成章了。

fn main() {
    let hl = HalfLine;
    let ls = LineSegment;
    let ret = hl.intersect(&ls);
    let ret1 = ls.intersect(&hl);
    println!("{:?}", ret);
    println!("{:?}", ret1);
}

struct Rect {
    x: u32,
    y: u32,
    width: u32,
    height: u32,
}

trait Area {
    fn rect(&self) -> Rect;
}

trait Intersect<T: Area> {
    fn intersect(&self, rhs: &T) -> bool;
}

impl<R, T> Intersect<R> for T
where
    R: Area,
    T: Area,
{
    fn intersect(&self, rhs: &R) -> bool {
        true
    }
}

struct HalfLine;
struct LineSegment;

impl Area for HalfLine {
    fn rect(&self) -> Rect {
        Rect {
            x: 0,
            y: 0,
            width: 100,
            height: 100,
        }
    }
}

impl Area for LineSegment {
    fn rect(&self) -> Rect {
        Rect {
            x: 0,
            y: 0,
            width: 100,
            height: 100,
        }
    }
}
Pikachu 2023-08-11 00:12

有个稍微有点狂野的路子,是写个macro来生成代码。

github.com/shanliu/lsys 2023-08-10 21:16

相互实现from不就完了么?

liyiheng 2023-08-10 20:52

退而求其次不再报错,但是很危险,一不留神就写错导致爆栈了:

pub trait Intersect<T> {
    fn intersect(&self, rhs: &T) -> bool;
}
struct Segment;
struct Ray;
impl<T> Intersect<T> for Ray
where
    T: Intersect<Ray>,
{
    fn intersect(&self, rhs: &T) -> bool {
        rhs.intersect(self)
    }
}
impl Intersect<Ray> for Segment {
    fn intersect(&self, rhs: &Ray) -> bool {
        rhs.intersect(self)
    }
}

--
👇
liyiheng: 我尝试这么写会报错,重复实现 trait。 也许可以参考 From 和 Into 分成两个 trait

pub trait Intersect<T> {
    fn intersect(&self, rhs: &T) -> bool;
}
struct Segment;
struct Ray;
impl Intersect<Ray> for Segment {
    fn intersect(&self, rhs: &Segment) -> bool {
        todo!()
    }
}
impl<T, U> Intersect<U> for T
where
    U: Intersect<T>,
{
    fn intersect(&self, ls: &U) -> bool {
        ls.intersect(self)
    }
}
liyiheng 2023-08-10 20:23

我尝试这么写会报错,重复实现 trait。 也许可以参考 From 和 Into 分成两个 trait

pub trait Intersect<T> {
    fn intersect(&self, rhs: &T) -> bool;
}
struct Segment;
struct Ray;
impl Intersect<Ray> for Segment {
    fn intersect(&self, rhs: &Segment) -> bool {
        todo!()
    }
}
impl<T, U> Intersect<U> for T
where
    U: Intersect<T>,
{
    fn intersect(&self, ls: &U) -> bool {
        ls.intersect(self)
    }
}
1 共 5 条评论, 1 页