[英]How to write a method that adds `self` as a mutable trait reference to a collection?
我有一个特征Foo
和一个struct Bar
。 Bar
有一个Vec
字段,其中包含实现Foo
任何引用。
trait Foo { }
struct Bar<'a> {
handlers: Vec<&'a mut Foo>,
}
我还有一个实现Foo
结构Stu
,并且有一个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
不满意
我该如何解决这个问题或实现我想要的最终目标?
更仔细地阅读错误方法:
特质绑定
&mut Stu: Foo
不满意
与:
impl Foo for Stu { }
您已经为Stu
实现了Foo
,而不是为&mut Stu
实现了Foo
。
在Rust中,值,不可变引用和可变引用是三个不同的实体,您可以独立地为它们中的任何一个实现特征。
第二种情况是&mut self
不匹配模式。 在常规模式匹配中, &mut a: &mut A
表示a
的类型为A
,实际上其他参数也是如此。
然而,令人困惑的是, &mut self
只是&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);
}
}
注意:注释生命周期时,不必全部注释生命周期; 只需为要限制的对象插入名称。
我已经修改了您的程序,使其包含显式的生存期<'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");
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.