我有一个特征Foo
和一个结构Bar
。 Bar
有一个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
如何解决这个问题或实现我期望的最终目标?
答案 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");
}