问题
I know inheritance is a bad word in the Rust world, however there must be some way, given the following struct
struct Glyph {
// Fields
}
to have a new Glyphs struct that is a wrapper for Vec<Glyph> methods (push, etc.) as well as fields and methods proper to itself?
回答1:
You can define a type alias (i.e. a synonym):
type Glyphs = Vec<Glyph>;
It is not a distinct type, so you can pass a Glyphs to any function that expects a compatible Vec, including generic functions.
You will not be able to add fields or inherent methods to this type directly. What you can do, though, is define an extension trait (i.e. a trait that exists for the sole purpose of adding methods to a type you didn't define; there's no special syntax for this) and have Glyphs implement it. If you use modules, you'll have to import the trait with use to bring the methods into scope.
trait GlyphsExt {
fn x(&self); // define extension method
}
impl GlyphsExt for Glyphs {
fn x(&self) {
// implement method here
}
}
回答2:
You can use Deref and DerefMut, like so:
use std::ops::{Deref, DerefMut};
struct Glyph;
struct Glyphs(Vec<Glyph>);
impl Glyphs {
fn new() -> Self {
Glyphs(vec![])
}
}
impl Deref for Glyphs {
type Target = Vec<Glyph>;
fn deref(&self) -> &Vec<Glyph> { &self.0 }
}
impl DerefMut for Glyphs {
fn deref_mut(&mut self) -> &mut Vec<Glyph> { &mut self.0 }
}
fn main() {
let mut gs = Glyphs::new();
gs.push(Glyph);
gs.push(Glyph);
println!("gs.len: {}", gs.len());
}
Note that this is not inheritance. A big limitation is that you absolutely cannot prevent someone from calling any of Vec's methods, since they can just manually deref a Glyphs into a Vec<Glyph>. You can "override" methods by defining them on Glyphs, but again, someone can just go behind your back by manually dereferencing a Glyphs.
You may also wish to read the Deref coercions chapter of the Rust Book.
回答3:
In my opinion, you shouldn't use Deref and DerefMut to emulate some aspects of inheritance. They exist for writing custom pointer types.
When you're writing a wrapper struct like this, you typically only need some of Vecs functionality. There may also be some invariants that need to hold. By implementing Deref and DerefMut you're making your Glyphs harder to reason about and easier to misuse. Avoiding to expose implementation details is generally also preferable.
So the solution would be to implement the functions you need on Glyphs. These are probably only a few. And if you really need all or most of Vecs functions and trait implementations, then a wrapper struct wasn't the right choice to begin with.
来源:https://stackoverflow.com/questions/31497584/how-can-i-wrap-another-type-and-add-fields-and-methods-to-it