'& self'和'&''self'有什么区别?

时间:2017-08-23 07:44:32

标签: struct rust lifetime

我最近遇到了一个错误,只需通过更改

即可解决
impl<'a> Foo<'a> {
    fn foo(&'a self, path: &str) -> Boo<'a> { /* */ }
}

impl<'a> Foo<'a> {
    fn foo(&self, path: &str) -> Boo { /* */ }
}

根据我的理解没有意义,因为我认为第二个版本与应用生命周期省略的第一个版本完全相同。

如果我们为方法引入了新的生命周期,那么根据nomicon中的这个例子就是这种情况。

fn get_mut(&mut self) -> &mut T;                        // elided
fn get_mut<'a>(&'a mut self) -> &'a mut T;              // expanded

那么这和我的第一段代码之间有什么区别。

1 个答案:

答案 0 :(得分:5)

'a中的fn foo(&'a self, ...) ...生命周期impl<'a>是为foo定义的,即所有'a次调用都是如此。

fn get_mut<'a>(&'a mut self) ...中的生命周期get_mut是为该函数定义的。 'a的不同来电可以为impl<'a> Foo<'a> { fn foo(&'a self, path: &str) -> Boo<'a> { /* */ } } 提供不同的值。

您的代码

&'a self

不是elided life的扩展。此代码将借用Foo<'a>的生命周期与结构Foo<'a>的生命周期联系起来。如果'aself不变,那么只要'a {@ 1}}就会继续借用impl<'a> Foo<'a> { fn foo<'b>(&'b self, path: &str) -> Boo<'b> { /* */ } }

正确的延长寿命

Foo

此代码不依赖于结构self的方差,以便能够以较短的生命周期借用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)); }

变体和不变结构之间的差异示例。

POST https://www.googleapis.com/androidpublisher/v2/applications/yourPackageNameHere/edits

Playground link