'& self'和'&'a self'有什么区别? [英] What is the difference between '&self' and '&'a self'?
问题描述
我最近遇到了一个错误,只需通过更改即可解决
I recently had an error which was simply resolved by changing
impl<'a> Foo<'a> {
fn foo(&'a self, path: &str) -> Boo<'a> { /* */ }
}
到
impl<'a> Foo<'a> {
fn foo(&self, path: &str) -> Boo { /* */ }
}
根据我的理解,这没有任何意义,因为我认为第二个版本与应用了生命周期省略的第一个完全相同.
which did not make sense according to my understanding, as I thought that the second version is exactly the same as the first with applied lifetime elision.
如果我们为该方法引入了新的生命周期,则根据 nomicon .
In case we introduce a new lifetime for the method this seems to be the case according this example from the nomicon.
fn get_mut(&mut self) -> &mut T; // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T; // expanded
那么这段代码和我的第一个代码片段之间有什么区别.
So what are the differences between this and my first code snipped.
推荐答案
fn foo(&'a self, ...) ...
中的生存期'a
是为impl<'a>
定义的,也就是说,所有foo
调用都相同.
Lifetime 'a
in fn foo(&'a self, ...) ...
is defined for impl<'a>
, that is it is the same for all foo
calls.
寿命'a
.不同的get_mut
调用可以具有不同的'a
值.
Lifetime 'a
in fn get_mut<'a>(&'a mut self) ...
is defined for the function. Different calls of get_mut
can have different values for 'a
.
您的代码
impl<'a> Foo<'a> {
fn foo(&'a self, path: &str) -> Boo<'a> { /* */ }
}
不是延长寿命.该代码将借用&'a self
的生存期与结构Foo<'a>
的生存期联系起来.如果Foo<'a>
在'a
上不变,那么只要'a
,self
应该保持借用.
is not the expansion of elided lifetime. This code ties lifetime of borrow &'a self
to the lifetime of structure Foo<'a>
. If Foo<'a>
is invariant over 'a
, then self
should remain borrowed as long as 'a
.
消除寿命的正确扩展是
impl<'a> Foo<'a> {
fn foo<'b>(&'b self, path: &str) -> Boo<'b> { /* */ }
}
此代码不依赖于结构Foo
的变化而能够借用self
来缩短生命周期.
This code doesn't depend on variance of structure Foo
to be able to borrow self
for shorter lifetimes.
变异结构和不变结构之间差异的例子.
Example of differences between variant and invariant structures.
use std::cell::Cell;
struct Variant<'a>(&'a u32);
struct Invariant<'a>(Cell<&'a u32>);
impl<'a> Variant<'a> {
fn foo(&'a self) -> &'a u32 {
self.0
}
}
impl<'a> Invariant<'a> {
fn foo(&'a self) -> &'a u32 {
self.0.get()
}
}
fn main() {
let val = 0;
let mut variant = Variant(&val);// variant: Variant<'long>
let mut invariant = Invariant(Cell::new(&val));// invariant: Invariant<'long>
{
let r = variant.foo();
// Pseudocode to explain what happens here
// let r: &'short u32 = Variant::<'short>::foo(&'short variant);
// Borrow of `variant` ends here, as it was borrowed for `'short` lifetime
// Compiler can do this conversion, because `Variant<'long>` is
// subtype of Variant<'short> and `&T` is variant over `T`
// thus `variant` of type `Variant<'long>` can be passed into the function
// Variant::<'short>::foo(&'short Variant<'short>)
}
// variant is not borrowed here
variant = Variant(&val);
{
let r = invariant.foo();
// compiler can't shorten lifetime of `Invariant`
// thus `invariant` is borrowed for `'long` lifetime
}
// Error. invariant is still borrowed here
//invariant = Invariant(Cell::new(&val));
}
这篇关于'& self'和'&'a self'有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!