如何为所有实现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
相关产品推荐
相关产品推荐

