“借来的价值不能长期生存”,但是为什么我们需要它长期生存呢?

时间:2019-01-12 13:42:01

标签: rust lifetime borrow-checker

有很多类似的问题,但是我找不到确切问题的答案。

在我的Rust代码中,我有一个泛型类型,并且想要实现一个方法,该方法引用对该类型的另一个实例的引用,然后实现另一个使用其参数但与第一个实例完全相同的方法的方法:

#[derive(Debug, PartialEq, Clone)]
pub struct Wrapper<T> {
    v: T,
}

impl<T> Wrapper<T> {
    pub fn f_ref(&self, _other: &Wrapper<T>) { /* ... */ }
    pub fn f_consume(&self, other: Wrapper<T>) {
        self.f_ref(&other)
    }
}

它可以编译。

现在我想做基本相同的事情,但是要实现一个特征。首先,需要参考的函数:

use std::ops::AddAssign;

impl<'a, T> AddAssign<&'a Wrapper<T>> for Wrapper<T> where T: AddAssign<&'a T> {
    fn add_assign(&mut self, other: &'a Wrapper<T>) {
        self.v += &other.v;
    }
}

#[test]
fn test() {
    let mut a = Wrapper { v: 1_i32 };
    let b = Wrapper { v: 2 };
    a += &b;
    drop(b);
    assert_eq!(a, Wrapper { v: 3 });
}

它也可以工作。

现在,我想基于已经拥有的AddAssign的实现来为Wrapper<T>实现AddAssign<&Wrapper<T>>。我了解如果T中包含引用,则会造成麻烦,因此,我确保其具有'static生存期。我对此表示满意:在我的程序中,我希望T就像是包裹在自定义结构中的数字的拥有矩阵。

impl<'a, T> AddAssign for Wrapper<T> where T: 'static + AddAssign<&'a T>, Wrapper<T>: 'static {
    fn add_assign(&mut self, other: Wrapper<T>) {
        *self += &other;
    }
}

它失败了。编译器说other+=表达式中使用了对它的引用后必须保持有效。但是,当我们在上面的test()函数中使用了这样的引用并将b放到那里(在这里起到other的作用)并稍后使用结果时,编译器同意可以。为什么?

我怀疑我需要为TWrapper<T>指定一些其他特征范围,但不了解这些界限应该是什么。

Code in playground.

0 个答案:

没有答案