【发布时间】:2021-12-28 17:39:09
【问题描述】:
例如,我希望每个MyTrait 都实现AddAssign<&'a Self>。这是我得到的,在将'a 放在编译器想要的位置之后:
trait MyTrait<'a>: 'a + std::ops::AddAssign<&'a Self> {}
fn func<'a, T: MyTrait<'a>>(a: &mut T, b: T) {
*a += &b;
}
此代码失败并出现以下错误:
error[E0597]: `b` does not live long enough
--> src/main.rs:4:11
|
3 | fn func<'a, T: MyTrait<'a>>(a: &mut T, b: T) {
| -- lifetime `'a` defined here
4 | *a += &b;
| ^^
| |
| borrowed value does not live long enough
| requires that `b` is borrowed for `'a`
5 | }
| - `b` dropped here while still borrowed
For more information about this error, try `rustc --explain E0597`.
我如何告诉编译器&b 将仅用于该总和期间?
【问题讨论】:
-
要回答您的问题,只需使用
b: &'a T而不是b: T。但是,我认为您可能真正想做的事情(AddAssign的一个版本,它采用引用而不是值)很遗憾,由于AddAssign的定义方式,这是不可能的。你会发现,如果你只使用b: &T,一开始它似乎可以工作,但你会遇到这样的问题,即对于非Copy类型,实际上不可能实现具有任意生命周期的MyTrait<'a>,这首先破坏了使用引用的全部意义。 -
在我的真实代码中,我不能有
b: &'a T,因为我求和的变量是本地的。我特别需要一个解决方案,其中b可以在a之前超出范围。由于语法限制,这可能是不可能的,但我不明白这从根本上是不可能的。 -
这不会是正确的,因为
AddAssign的实现者可以假设加数永远存在;例如,如果允许引用,您可以实现AddAssign以将引用推送到内部堆栈,该堆栈在引用无效后将持续存在。我的建议:创建您自己的AddAssign版本,使用引用代替。 -
@Coder-256 回答您的问题,“如果我们有
foo += &bar,当bar被删除时foo.vec会发生什么?”,那么foo必须在@ 之前被删除987654345@,这从根本上没有错。但是这样的特征实现与我的特征约束不匹配,现在我用@kmdreko 的答案修复了它。在我最初的尝试中,我说引用的对象必须比MyTrait对象寿命长,但在接受的答案中没有这样的限制。
标签: rust borrow-checker