(我无法拿出好标题,请随时对其进行纠正)。
我具有二进制特征resolve
。
pub trait Resolve<RHS = Self> {
type Output;
fn resolve(self, rhs: RHS) -> Self::Output;
}
我为诸如struct Foo
这样的琐碎事物实现了特征。
struct Foo;
impl <'a, 'b> Resolve<&'b Foo> for &'a Foo {
type Output = Foo;
fn resolve(self, rhs: &'b Foo) -> Self::Output {
unimplemented!()
}
}
如您所见,两个参数都是引用(self
是&'a Foo
,而rhs
是&'b Foo
)。
如果我现在写
fn main() {
let a: &Foo = &Foo;
let b = Foo;
a.resolve(&b);
}
它可以正常编译,但是如果我尝试在结构Signal
上实现它,它将无法正常工作。
pub struct Signal<'a, T> {
ps: Vec<&'a T>,
}
impl<'a, T: Resolve<&'a T, Output = T> + 'a> Signal<'a, T> {
pub fn foo(&mut self) {
let a: &T = &self.ps[0];
let b = &self.ps[1];
a.resolve(b);
}
}
error[E0507]: cannot move out of borrowed content
--> src/main.rs:25:9
|
25 | a.resolve(b);
| ^ cannot move out of borrowed content
如何使此示例正常工作? (playground)
答案 0 :(得分:4)
绑定到foo
的特征仅表示T
实现Resolve
,但是您尝试对类型为.resolve()
的值调用&T
。
相反,要说对T
的引用必须实现Resolve
,则需要一个higher-ranked trait bound:
impl<'a, T> Signal<'a, T>
where
for<'b> &'b T: Resolve<&'a T, Output = T>,
{
pub fn foo(&mut self) { ... }
}
答案 1 :(得分:1)
考虑了这一点,我想出了一个不依赖HRTB的简单解决方案。
impl<'a, T> Signal<'a, T>
where
&'a T: Resolve<&'a T, Output = T> + 'a,
{
pub fn foo(&mut self) {
let a: &T = &self.ps[0];
let b = &self.ps[1];
a.resolve(b);
}
}
这与&T
实现Resolve
的作用相同,即描述,但是不需要HRTB。
为此,您必须使用where clause,但除此之外,这是一个很好的解决方案。