比方说我有一些特点:
trait MyTrait {
fn function1(&self);
}
Run Code Online (Sandbox Code Playgroud)
和一些实现它的类型:
struct MyStruct {
number: i32,
}
impl MyTrait for MyStruct {
fn function1(&self) {
printn!("{}", self.number);
}
}
Run Code Online (Sandbox Code Playgroud)
现在我有另一种类型,它想要实现的东西MyTrait.它不关心他们是否拥有.从阅读周围,这听起来像做到这一点的正确方法是把它取Borrow<X>来代替X或&X或什么的.这使得它拿样东西X,或Rc<X>或Box<X>等..
当X具体类型的时候,我有这个工作,但是当X一个特性时我该如何使它工作?
这是我先尝试过的:
struct Consumer<T> {
inner: T
}
impl<T: Borrow<MyTrait>> Consumer<T> {
pub fn new(inner: T) -> Consumer<T> {
Consumer {
inner: inner
}
}
pub fn do_stuff(&self) {
self.inner.borrow().function1();
}
}
fn main() {
// I want to eventually be able to swap this out for x = Rc::new(MyStruct ...
// but I'll keep it simple for now.
let x = MyStruct { number: 42 };
let c = Consumer::new(x);
c.do_stuff();
}
Run Code Online (Sandbox Code Playgroud)
这还不行,因为MyStruct实现Borrow<MyStruct>,但不是Borrow<MyTrait>.好的,让我们试着实现:
impl Borrow<MyTrait> for MyStruct {
fn borrow(&self) -> &MyTrait {
self
}
}
Run Code Online (Sandbox Code Playgroud)
这给了我以下错误,我不明白:
Run Code Online (Sandbox Code Playgroud)<anon>:33:5: 35:6 error: method `borrow` has an incompatible type for trait: expected bound lifetime parameter , found concrete lifetime [E0053] <anon>:33 fn borrow(&self) -> &MyTrait { <anon>:34 self <anon>:35 } <anon>:33:5: 35:6 help: see the detailed explanation for E0053 error: aborting due to previous error playpen: application terminated with error code 101
什么?在那里根本没有提到任何具体的生命周期,并且Borrow没有提到任何生命周期.我很难过.
首先,我的假设是否正确使用Borrow是正确的方法?如果是这样,我该如何实现Borrow特质?
编写实现的正确方法是:
impl<'a> Borrow<MyTrait + 'a> for MyStruct {
fn borrow(&self) -> &(MyTrait + 'a) {
self
}
}
Run Code Online (Sandbox Code Playgroud)
可以使用生命周期限制来限制特征对象.这是因为实现特征的类型可能包含引用,在某些情况下,我们需要能够区分依赖于借来的对象的对象和不支持对象的对象.如果没有指定生命期限,我认为它默认为'static; 但是,指定&(MyTrait + 'static)为返回类型编译(它不太通用,所以你应该支持上面的通用解决方案),所以你遇到的问题比那更微妙......