为实现Trait的类型实现Borrow <Trait>

Bil*_*ser 7 rust

比方说我有一些特点:

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)

这给了我以下错误,我不明白:

<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
Run Code Online (Sandbox Code Playgroud)

什么?在那里根本没有提到任何具体的生命周期,并且Borrow没有提到任何生命周期.我很难过.

首先,我的假设是否正确使用Borrow是正确的方法?如果是这样,我该如何实现Borrow特质?

Fra*_*gné 7

编写实现的正确方法是:

impl<'a> Borrow<MyTrait + 'a> for MyStruct {
    fn borrow(&self) -> &(MyTrait + 'a) {
        self
    }
}
Run Code Online (Sandbox Code Playgroud)

可以使用生命周期限制来限制特征对象.这是因为实现特征的类型可能包含引用,在某些情况下,我们需要能够区分依赖于借来的对象的对象和不支持对象的对象.如果没有指定生命期限,我认为它默认为'static; 但是,指定&(MyTrait + 'static)为返回类型编译(它不太通用,所以你应该支持上面的通用解决方案),所以你遇到的问题比那更微妙......