pub struct Writer<'a> {
target: &'a mut String,
}
impl<'a> Writer<'a> {
fn indent<'b>(&'b mut self) -> &'a String {
self.target
}
}
编译此代码会导致以下错误:
error: lifetime may not live long enough
--> src/bin/main29.rs:19:9
|
17 | impl<'a> Writer<'a> {
| -- lifetime `'a` defined here
18 | fn indent<'b>(&'b mut self) -> &'a String {
| -- lifetime `'b` defined here
19 | self.target
| ^^^^^^^^^^^ method was supposed to return data with lifetime `'a` but it is returning data with lifetime `'b`
|
= help: consider adding the following bound: `'b: 'a`
为什么这个 Rust 代码无法编译?我以为这会起作用。
因为属于
&'b Writer<'a>
的任何数据仅在 'a
和 'b'
中较短的时间内存在,但您试图返回在 'a
中存在的数据。正如编译器所说,这仅在 'b: 'a
时才有效。
您可以通过应用绑定
'b: 'a
来解决此问题,或者更简单地编写 &'a mut self
,但我强烈建议您不要表达 &'a T<'a>
形式的类型;解决这种不变性是非常痛苦的。更简单的实现是
impl Writer<'_> {
// or better yet, indent(&self) -> &str
fn indent(&mut self) -> &String {
self.target
}
}
这样做的优点是,编译器可以正确推断匿名的生命周期。这是有效的,因为一般来说,编译器会阻止你构造一个
&'a Writer<'b>
,其中 'a
严格地比 'b
长,因为这样的类型可能包含悬空引用;因此,也没有必要将该责任强加给函数签名。