我有一个程序,我不知道如何推理。我在特征A
上定义了具体的生命周期,A
由类型T : A
参数化。 refine
的一个特征函数A
采用&'a mut self
参数并返回Vec<T>
。
假设我有两个结构U
和V
,这样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());
}
答案 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的评论,这澄清了很好的事情。