对于第二个问题(避免重复相同的实现coordinate
),我想向您展示基于宏的解决方案。
有趣的是,它让您拥有3个特征而不是2个特征,因此它的方向与第一个问题的方向完全相反。我想你不可能拥有一切!:)
// factoring out the Coordinates trait from BasicInfo trait Coordinates { fn coordinate(&self) -> (f64, f64); } // but we can require implementors of BasicInfo to also impl Coordinates trait BasicInfo: Coordinates { fn area(&self) -> f64; } // helper macro to avoid repetition of "basic" impl Coordinates macro_rules! impl_Coordinates { ($T:ident) => { impl Coordinates for $T { fn coordinate(&self) -> (f64, f64) { (self.x, self.y) } } } } #[derive(Debug)] struct Circle { x: f64, y: f64, radius: f64, } #[derive(Debug)] struct Square { x: f64, y: f64, width: f64, sides: i32, } // the macro here will expand to identical implementations // for Circle and Square. There are also more clever (but a bit // harder to understand) ways to write the macro, so you can // just do impl_Coordinates!(Circle, Square, Triangle, OtherShape) // instead of repeating impl_Coordinates! impl_Coordinates!(Circle); impl_Coordinates!(Square); trait Sides { fn has_sides(&self) -> i32; } impl BasicInfo for Circle { fn area(&self) -> f64 { std::f64::consts::PI * (self.radius * self.radius) } } impl BasicInfo for Square { fn area(&self) -> f64 { self.width.powf(2.0) } } impl Sides for Square { fn has_sides(&self) -> i32 { self.sides } }