【发布时间】:2017-05-02 14:25:06
【问题描述】:
此代码无法通过可怕的借用检查器 (playground):
struct Data {
a: i32,
b: i32,
c: i32,
}
impl Data {
fn reference_to_a(&mut self) -> &i32 {
self.c = 1;
&self.a
}
fn get_b(&self) -> i32 {
self.b
}
}
fn main() {
let mut dat = Data{ a: 1, b: 2, c: 3 };
let aref = dat.reference_to_a();
println!("{}", dat.get_b());
}
由于实现了非词法生命周期,因此触发错误是必需的:
fn main() {
let mut dat = Data { a: 1, b: 2, c: 3 };
let aref = dat.reference_to_a();
let b = dat.get_b();
println!("{:?}, {}", aref, b);
}
错误:
error[E0502]: cannot borrow `dat` as immutable because it is also borrowed as mutable
--> <anon>:19:20
|
18 | let aref = dat.reference_to_a();
| --- mutable borrow occurs here
19 | println!("{}", dat.get_b());
| ^^^ immutable borrow occurs here
20 | }
| - mutable borrow ends here
这是为什么?我会认为dat 的可变借用在reference_to_a() 返回时会转换为不可变借用,因为该函数仅返回不可变引用。借阅检查器还不够聪明吗?这是计划好的吗?有办法解决吗?
【问题讨论】:
-
Limits of Lifetimes。这完全一样。
-
@Stargateur:我不认为“去糖”代码是为了编译;这只是为了说明。
-
@Stargateur:不,它没有帮助。需要限制
loanplay.rust-lang.org/…的生命周期 -
@aSpex:是的,看起来确实是一样的。但是文档没有提出解决方案或解决方法?
-
哦,确实“根据我们真正关心的引用语义,这个程序显然是正确的,但是生命周期系统太粗粒度,无法处理。”。所以唯一的解决方案是使用独立的作用域。 @aSpex 你应该发布一个答案。
标签: rust borrow-checker