如何使用引用的原始生命周期获取存储在结构中的引用?

时间:2018-02-17 04:59:16

标签: rust

我正在尝试运行以下代码。很容易理解inner()的返回值的生命周期与'static生命周期不兼容,但如何在不更改main()函数的情况下完成此工作?

struct Wrapper<'a>(&'a str);

impl<'a> Wrapper<'a> {
    fn inner(&self) -> &str {
        self.0
    }
}

pub fn main() {
    let x = "hello";
    let wrapper = Wrapper(&x);
    let _: &'static str = wrapper.inner();
}
error[E0597]: `wrapper` does not live long enough
  --> src/main.rs:12:27
   |
12 |     let _: &'static str = wrapper.inner();
   |                           ^^^^^^^ borrowed value does not live long enough
13 | }
   | - borrowed value only lives until here
   |
   = note: borrowed value must be valid for the static lifetime...

我从一个我正在学习的课程中看到了这个例子,但我仍然坚持理解如何使这项工作。

1 个答案:

答案 0 :(得分:3)

您所要做的就是更改inner的签名,以便返回类型与Wrapper字段的类型匹配:

impl<'a> Wrapper<'a> {
    fn inner(&self) -> &'a str {
        //              ^^ 'a added here
        self.0
    }
}

使用wrapper初始化变量Wrapper(&x)时,编译器会推断其类型为Wrapper<'static>,因为x的生命周期为'static(所有文字都是字符串的生命周期为'static。因此,当您在inner上致电Wrapper<'static>时,返回类型为&'static str

如果我们不向签名添加'a,则返回值的生命周期是Wrapper本身的生命周期。如果我们完整地写出生命周期,这一点就更明显了:

impl<'a> Wrapper<'a> {
    fn inner<'b>(&'b self) -> &'b str {
        self.0
    }
}

您的Wrapper生命周期为'static,因为它位于本地变量中;它的生命将在函数返回时结束 - main在生命周期中并不特殊。因此,返回的字符串切片也不具有'static生存期。

现在,也许你想知道,“如果原始字符串的生命周期为'static,为什么返回它的生命周期不同?”。重要的是要理解生命周期不必是准确的;如果有必要,可以缩短它们。终身的目标是确保你的引用被删除后不使用引用;如果你声称一个值的生命周期短于实际值,那么它是完全安全的,它只是(可能不必要地)限制了引用的使用时间。