我需要为来自外部 crate 的对象实现 fmt::Display
方法,所以我为这个对象创建了一个包装器。我希望能够使用原始对象中的所有方法,而不必重新定义所有方法。我试图按照很棒的 IRC 频道#rust-beginners
的建议实现Deref
:
struct CustomMap(ObjectComingFromAnExternalCrate<char, char>);
impl std::ops::Deref for CustomMap {
type Target = ObjectComingFromAnExternalCrate<char, char>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
fn main() {
let cm = CustomMap::with_capacity(10);
println!("Hello, world!");
}
但是,我收到此错误:
error: no associated item named `with_capacity` found for type `CustomMap` in the current scope
--> <anon>:16:13
|
16 | let a = CustomMap::with_capacity(10);
| ^^^^^^^^^^^^^^^^^^^^^^^^
我认为这是因为deref()
不适用于相关功能。
我该如何解决此问题?重新实现我使用的每个关联函数,只是为了能够实现我需要的一种方法似乎有点矫枉过正。
Newtypes是专门为提供封装而设计的,所以它们不一定适合仅仅"添加新的东西"。
话虽如此,结合:
-
Deref
和DerefMut
才能访问这些方法 -
From
和Into
,可以轻松地从一个转换为另一个 - 或者使内部类型
pub
应该能够解决这个问题。
From
/Into
建议来自这样一个事实,即大多数相关函数通常是构造函数1。
impl From<ObjectComingFromAnExternalCrate<char, char>> for CustomMap { ... }
然后你可以做:
let cm: CustomMap = ObjectComingFromAnExternalCrate<char, char>::with_capacity(10).into();
另一种解决方案是将CustomMap
定义为:
struct CustomMap(pub ObjectComingFromAnExternalCrate<char, char>);
然后:
let cm = CustomMap(ObjectComingFromAnExternalCrate<char, char>::with_capacity(10));
如果您不希望强制执行任何其他不变量,并且不关心封装,那么两者都应该让您继续前进。
1指针类型(如 Rc
)大量使用它们以避免隐藏 Deref'ed 键入的方法。