There is nothing that exactly matches that. There are two concepts that come to mind.
-
Structural composition
struct Person { age: u8, } struct Child { person: Person, has_toy: bool, } impl Person { fn new(age: u8) -> Self { Person { age: age } } fn age(&self) -> u8 { self.age } } impl Child { fn new(age: u8, has_toy: bool) -> Self { Child { person: Person::new(age), has_toy: has_toy } } fn age(&self) -> u8 { self.person.age() } } fn main() { let p = Person::new(42); let c = Child::new(7, true); println!("I am {}", p.age()); println!("My child is {}", c.age()); }
You can simply embed one struct into another. The memory layout is nice and compact, but you have to manually delegate all the methods from
Person
toChild
or lend out a&Person
. -
Traits
trait SayHi { fn say_hi(&self); } struct Person { age: u8, } struct Child { age: u8, has_toy: bool, } impl SayHi for Person { fn say_hi(&self) { println!("Greetings. I am {}", self.age) } } impl SayHi for Child { fn say_hi(&self) { if self.has_toy { println!("I'm only {}, but I have a toy!", self.age) } else { println!("I'm only {}, and I don't even have a toy!", self.age) } } } fn greet<T>(thing: T) where T: SayHi { thing.say_hi() } fn main() { let p = Person { age: 42 }; let c = Child { age: 7, has_toy: true }; greet(p); greet(c); }
You can combine these two concepts, of course.
As DK. mentions, you could choose to implement Deref
or DerefMut
. However, I do not agree that these traits should be used in this manner. My argument is akin to the argument that using classical object-oriented inheritance simply for code reuse is the wrong thing. “Favor composition over inheritance” => “favor composition over Deref
“. However, I do hold out hope for a language feature that enables succinct delegation, reducing the annoyance of composition.