可变寿命与不可变寿命

时间:2016-01-02 16:38:24

标签: rust

我有一个程序,我不知道如何推理。我在特征A上定义了具体的生命周期,A由类型T : A参数化。 refine的一个特征函数A采用&'a mut self参数并返回Vec<T>

假设我有两个结构UV,这样V的字段的类型为&'a U,而U的结构为refine定义为:

fn refine(&'a mut self) -> Vec<V<'a>>

如果我直接在V U的实现主体中构造refine,编译器会告诉我self的生存时间不够长。但是,如果我在V的实现函数中构造U,我们称之为make_v,其签名为:

fn make_v<'a>(&'a self) -> V<'a>

似乎工作正常。我对两者的寿命要求是如何不同感到困惑。我有一个rust playground工作示例,这里又是后人:

trait A<'a, T : A<'a> = Self> {
    fn refine(&'a mut self) -> Vec<T>;
}

#[derive(Clone, Debug)]
struct V<'a> {
    u: &'a U,
    id: usize
}

#[derive(Debug)]
struct U {
    id: u64
}

impl U {
    fn make_v<'a>(&'a self, i: usize) -> V<'a> {
        V { u: &self, id: i }
    }
}

impl<'a> A<'a> for V<'a> {
    fn refine(&'a mut self) -> Vec<V<'a>> {
        vec![self.clone(), self.clone(), self.clone()]
    }
}

impl<'a> A<'a, V<'a>> for U {
    fn refine(&'a mut self) -> Vec<V<'a>> {
        let mut v = Vec::new();
        for i in 0..3 {
            // This doesn't compile
            // v.push(V { u: &self, id: i });

            // This does compile...?
            v.push(self.make_v(i));
        }

        v
    }
}

fn main() {
    let mut u = U { id: 0 };
    println!("{:?}", u.refine());
}

1 个答案:

答案 0 :(得分:4)

v.push(V { u: &self, id: i });

正在调用 auto-deref ,因此最终为

v.push(V { u: *&self, id: i });

&self&'k &'a mut T,其中'k&mut指针的范围(不是指向对象)。这意味着借用它有时会受到限制。

self.make_ref版本的做法不同;作为再利用。这看起来像&*self。在这种情况下,外部引用是一个具有生命周期'a的对象,因此可以是生命周期'a

在这种情况下写self只会自动处理。

感谢@fjh的评论,这澄清了很好的事情。