如何编写一个方法,将“self”添加为集合的可变特征引用?

时间:2016-06-28 13:48:41

标签: rust

我有一个特征Foo和一个结构BarBar有一个Vec字段,其中包含实现Foo的任何引用。

trait Foo { }

struct Bar<'a> {
    handlers: Vec<&'a mut Foo>,
}

我有另一个实现Stu的结构Foo,并有一个方法add将自己添加到bar

struct Stu { }

impl Foo for Stu { }

impl Stu {
    fn add(&mut self, bar: &mut Bar) {
        bar.handlers.push(&mut self);
    }
}

因为有很多类型的结构实现Foo并且add方法中完成的操作是多种多样的,我需要一个包含所有结构的结构(这里是Bar) ,我写了上面的代码。但是编译器抱怨道:

  

不满足特征限制&mut Stu: Foo

如何解决这个问题或实现我期望的最终目标?

2 个答案:

答案 0 :(得分:4)

更仔细地阅读错误方法:

  

不满足特征限制&mut Stu: Foo

impl Foo for Stu { }

您已为Foo实施Stu,而不是&mut Stu

在Rust中,值,不可变引用和可变引用是三个不同的实体,您可以独立地为它们中的任何一个实现特征。

第二个案例是&mut self不是模式匹配。在常规模式匹配中,&mut a: &mut A表示a的类型为A,而其他参数确实如此处理。

然而,令人困惑的是,&mut self只是self: &mut Self的语法糖......

因此self的类型为&mut Stu,因此您不应在push来电中进一步限定它。

因此,您必须将代码更正为:

impl Stu {
    fn add(&mut self, bar: &mut Bar) {
        bar.handlers.push(self);
    }
}

此时,您将收到有关终身限制的错误:此处不保证self将超过Bar。您需要对其进行注释(使用相同的生命周期)才能使其工作:

impl Stu {
    fn add<'a>(&'a mut self, bar: &mut Bar<'a>) {
        bar.handlers.push(self);
    }
}

注意:在注释生命周期时,没有必要对它们进行全部注释;只需要为要约束的人插入名称。

答案 1 :(得分:1)

我已修改您的程序以包含显式生命周期<'a, 'b>,这会导致编译成功。

trait Foo { }

struct Bar<'a> {
    pub handlers: Vec<&'a mut Foo>,
}

struct Stu;

impl Foo for Stu { }

impl Stu {
    fn add<'a,'b> (&'a mut self, bar: &'b mut Bar<'a>) {
        bar.handlers.push(self);
    }
}
fn main(){
    println!("{:?}", "success");
}