我正在尝试运行以下代码。很容易理解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...
我从一个我正在学习的课程中看到了这个例子,但我仍然坚持理解如何使这项工作。
答案 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
,为什么返回它的生命周期不同?”。重要的是要理解生命周期不必是准确的;如果有必要,可以缩短它们。终身的目标是确保你的引用被删除后不使用引用;如果你声称一个值的生命周期短于实际值,那么它是完全安全的,它只是(可能不必要地)限制了引用的使用时间。