Oyr*_*ren 4 lifetime rust borrow-checker
为什么下面的代码可以编译通过?
我希望 Rust 编译器能告诉我
设置参考时“借用的价值不够长”
(store.barber.set(Some(&barber));
因为理发师的寿命比商店短。
use core::cell::Cell;
struct Shop<'a> {
barber: Cell<Option<&'a Barber<'a>>>,
}
struct Barber<'a> {
shop: Cell<Option<&'a Shop<'a>>>,
}
fn main() {
let shop = Shop { barber: Cell::new(None) };
{
let barber = Barber { shop: Cell::new(Some(&shop))};
shop.barber.set(Some(&barber));
}
}
Run Code Online (Sandbox Code Playgroud)
@jmb 的回答证实了我的假设(此处)。
代码示例来自这里。但我仍然不清楚为什么整个事情会起作用或者我的误解在哪里。
我在 @Netwaves 答案上评论的代码。
万一链接不再起作用并澄清问题。
内部作用域只是为了让生命周期更加清晰。
用法看起来更像是这样:
use core::cell::Cell;
struct Shop<'a> {
barber: Cell<Option<&'a Barber<'a>>>,
shop_state: Cell<bool>,
}
impl<'a> Shop<'a> {
fn change_barber_state(&self) {
self.barber.get().unwrap().change_state();
}
fn change_state(&self) {
self.shop_state.set(!self.shop_state.get());
}
}
struct Barber<'a> {
shop: Cell<Option<&'a Shop<'a>>>,
barber_state: Cell<bool>,
}
impl<'a> Barber<'a> {
fn change_state(&self) {
self.barber_state.set(!self.barber_state.get());
}
fn change_shop_state(&self) {
self.shop.get().unwrap().change_state();
}
}
fn main() {
let shop = Shop {
barber: Cell::new(None),
shop_state: Cell::new(false),
};
let barber = Barber {
shop: Cell::new(Some(&shop)),
barber_state: Cell::new(false),
};
shop.barber.set(Some(&barber));
println!("{:?}", barber.barber_state);
println!("{:?}", shop.shop_state);
shop.change_barber_state();
barber.change_shop_state();
println!("{:?}", barber.barber_state);
println!("{:?}", shop.shop_state);
}
Run Code Online (Sandbox Code Playgroud)
在相同的范围内,寿命是否相同?
我认为生命周期也是通过释放资源来给出的,这与声明的顺序相反。或者这仅在实施drop特征时才相关?
为什么这种相互引用结构可以在 Rust 中以指定的生命周期工作?
确实如此,因为根据您的代码,它实际上寿命足够长。
问题(没问题)是您shop在内部作用域之后不再使用,因此编译器足够聪明,可以说您的程序没有任何问题。但如果你添加一个访问权限,他就会开始抱怨,并且有充分的理由:
fn main() {
let shop = Shop { barber: Cell::new(None) };
{
let barber = Barber { shop: Cell::new(Some(&shop))};
shop.barber.set(Some(&barber));
}
shop.barber.get();
}
Run Code Online (Sandbox Code Playgroud)
无法编译:
error[E0597]: `barber` does not live long enough
--> src/main.rs:15:30
|
15 | shop.barber.set(Some(&barber));
| ^^^^^^^ borrowed value does not live long enough
16 | }
| - `barber` dropped here while still borrowed
17 | shop.barber.get();
| ----------------- borrow later used here
Run Code Online (Sandbox Code Playgroud)
error[E0597]: `barber` does not live long enough
--> src/main.rs:15:30
|
15 | shop.barber.set(Some(&barber));
| ^^^^^^^ borrowed value does not live long enough
16 | }
| - `barber` dropped here while still borrowed
17 | shop.barber.get();
| ----------------- borrow later used here
Run Code Online (Sandbox Code Playgroud)
为什么你认为这不应该编译?
显然,直到主要完成时,两者的shop寿命barber都相同。在这种情况下,free 的顺序并不重要,因为编译器已经知道它们都不会再被使用,所以上面的代码是完全安全的。
| 归档时间: |
|
| 查看次数: |
96 次 |
| 最近记录: |