我知道继承在Rust世界中是一个坏词,但是必须有某种方式,给定以下结构
struct Glyph {
// Fields
}
有一个新的Glyphs
结构,它是Vec<Glyph>
方法(push
等)的包装器,以及适合自己的字段和方法吗?
答案 0 :(得分:4)
您可以定义类型别名(即同义词):
type Glyphs = Vec<Glyph>;
它不是一个独特的类型,因此您可以将Glyphs
传递给任何需要兼容Vec
的函数,包括泛型函数。
您将无法直接向此类型添加字段或固有方法。但是,你可以做的是定义一个扩展特征(即一个特性,其唯一目的是为你没有定义的类型添加方法;这里没有特殊的语法)并具有{ {1}}实现它。如果您使用模块,则必须使用Glyphs
导入特征以将方法纳入范围。
use
答案 1 :(得分:3)
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());
}
请注意,此不是继承。一个很大的限制是你绝对无法阻止某人调用任何Vec
的方法,因为他们只能手动将Glyphs
解析为Vec<Glyph>
。您可以通过在Glyphs
上定义方法来“覆盖”这些方法,但有些人可以通过手动取消引用Glyphs
来支持这些方法。
答案 2 :(得分:2)
在我看来,你不应该使用Deref和DerefMut来模拟继承的某些方面。它们用于编写自定义指针类型。
当你编写这样的包装器结构时,通常只需要一些Vec
的功能。可能还有一些不变量需要持有。通过实施Deref
和DerefMut
,您的Glyphs
难以推理,更容易被滥用。避免公开实现细节通常也是优选的。
因此,解决方案是在Glyphs
上实现您需要的功能。这些可能只是少数几个。如果你真的需要全部或大部分Vec
函数和特征实现,那么封装结构不是开始时的正确选择。