You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为所有实现HasPos的类型实现HasShape trait?

Rust Trait 实现问题:让 HasPos 类型自动适配 HasShape

现有代码定义

首先是 HasShape 和 Drawable trait 的定义:

trait HasShape {
    fn ref_vertices(&self) -> &Vec<Vertex>;
    fn ref_vbo(&self) -> &VertexBuffer<Vertex>;
    // 该 trait 的其他方法
}

trait Drawable {
    fn draw(&self, target: &Frame);
}

impl<T> Drawable for T
where T: HasShape
{
    fn draw(&self, target: &Frame) {
        let vertices = self.ref_vertices();
        // 使用 HasShape 要求的字段
    }
}

接着是持有形状对象的 HasPos 和操作 trait Manipulate:

trait HasPos<S>
where
    S: HasShape
{
    fn ref_shape(&self) -> &S;
    fn ref_pos(&self) -> &Vector2f32;
    // 其余方法风格与 HasShape 一致
}

trait Manipulate<S>
where S: HasShape
{
    fn translate(&self, x: f32, y: f32);
    // 其余方法用于修改 HasPos 的字段
}

需求

希望为所有实现 HasPos 的类型自动实现 HasShape trait,让这些类型可以直接替代 HasShape 对象使用,进而调用 Drawable 的 draw 方法。

错误的尝试

你之前的写法存在循环约束问题:

impl<T: HasPos<T>> HasShape for T
where T: HasShape
{
    fn ref_vertices(&self) -> &Vec<Vertex>{
        self.ref_shape().ref_vertices()
    }
    // HasShape 的所有方法都通过 HasPos 中的对象获取对应字段
}

这里的约束 T: HasPos<T> 要求类型 T 自身是 HasPos 持有的形状类型,同时又要求 T: HasShape,形成了无意义的循环,而且不符合 HasPos 持有独立形状对象的设计逻辑。

正确的实现方式

正确的做法是针对任意类型 T 和形状类型 S,当 T 实现了 HasPos<S> 且 S 实现 HasShape 时,为 T 实现 HasShape,所有方法都委托给 ref_shape() 返回的形状对象:

impl<T, S> HasShape for T
where
    S: HasShape,
    T: HasPos<S>,
{
    fn ref_vertices(&self) -> &Vec<Vertex> {
        self.ref_shape().ref_vertices()
    }

    fn ref_vbo(&self) -> &VertexBuffer<Vertex> {
        self.ref_shape().ref_vbo()
    }

    // 实现 HasShape 的其他方法,同样委托给 self.ref_shape()
}

这样一来,任何实现了 HasPos<S>(其中 S 是 HasShape 类型)的 T,都会自动获得 HasShape 的实现,进而可以调用 Drawable 的 draw 方法,完全符合你的需求。

内容的提问来源于stack exchange,提问作者Tristen Gordon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 06:30:46