错误[E0502]:不能借用`vector`作为不可变的,因为它也被借用为可变的
error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable
在一个函数内,我试图将一个值推入一个向量,然后 return 对该值的引用,它位于向量内。遗憾的是,它不起作用,我收到以下错误:
error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable
--> src\lib.rs:19:19
|
18 | let _unit_0 = push_and_get(&mut vector);
| ----------- mutable borrow occurs here
19 | let _unit_1 = vector.last().unwrap();
| ^^^^^^ immutable borrow occurs here
20 | drop(_unit_0);
| ------- mutable borrow later used here
这是我的代码,有两个函数(this_works
、this_does_not_work
),据我所知,它们做同样的事情,但只有一个有效。
fn this_works() {
let mut vector = Vec::new();
vector.push(());
let _unit_0 = vector.last().unwrap();
let _unit_1 = vector.last().unwrap();
}
fn this_does_not_work() {
let mut vector = Vec::new();
let _unit_0 = push_and_get(&mut vector);
let _unit_1 = vector.last().unwrap();
drop(_unit_0); // Added, to make the error reappear
}
fn push_and_get(vector: &mut Vec<()>) -> &() {
vector.push(());
vector.last().unwrap()
}
是否有任何方法可以使 push_and_get
功能正常工作,或者由于 Rust 的限制而无法正常工作?如果是第一个,我怎样才能让它工作?如果是后者,是否有任何计划来解决这个特定问题,或者是否有任何充分的理由说明为什么不应该解决这个问题?
经过更多测试,我想我现在可以回答我自己的问题了。提供的示例可以进一步简化以显示核心问题。这是重现错误所需的实际最少代码量:
// I have embedded the error message as comments
fn main() {
let mut owned: () = ();
let ref0: &() = &mut owned;
// ---------- mutable borrow occurs here
let ref1: &() = &owned;
// ^^^^^^ immutable borrow occurs here
drop(ref0);
// ---- mutable borrow later used here
}
归根结底,Rust 允许将 &mut
转换为 &
,但仅限于理论上。实际上,一旦您使用从可变借用创建的借用,同时有另一个常规借用,编译器突然意识到,转换后的借用仍然是可变借用。类型检查器在撒谎。
总之,不可能将 push() 和 last() 组合成一个函数。
P.S。如果 Rust 支持从 &mut
到 &
的真正转换,那会很好,将来不会产生上述错误。
在一个函数内,我试图将一个值推入一个向量,然后 return 对该值的引用,它位于向量内。遗憾的是,它不起作用,我收到以下错误:
error[E0502]: cannot borrow `vector` as immutable because it is also borrowed as mutable
--> src\lib.rs:19:19
|
18 | let _unit_0 = push_and_get(&mut vector);
| ----------- mutable borrow occurs here
19 | let _unit_1 = vector.last().unwrap();
| ^^^^^^ immutable borrow occurs here
20 | drop(_unit_0);
| ------- mutable borrow later used here
这是我的代码,有两个函数(this_works
、this_does_not_work
),据我所知,它们做同样的事情,但只有一个有效。
fn this_works() {
let mut vector = Vec::new();
vector.push(());
let _unit_0 = vector.last().unwrap();
let _unit_1 = vector.last().unwrap();
}
fn this_does_not_work() {
let mut vector = Vec::new();
let _unit_0 = push_and_get(&mut vector);
let _unit_1 = vector.last().unwrap();
drop(_unit_0); // Added, to make the error reappear
}
fn push_and_get(vector: &mut Vec<()>) -> &() {
vector.push(());
vector.last().unwrap()
}
是否有任何方法可以使 push_and_get
功能正常工作,或者由于 Rust 的限制而无法正常工作?如果是第一个,我怎样才能让它工作?如果是后者,是否有任何计划来解决这个特定问题,或者是否有任何充分的理由说明为什么不应该解决这个问题?
经过更多测试,我想我现在可以回答我自己的问题了。提供的示例可以进一步简化以显示核心问题。这是重现错误所需的实际最少代码量:
// I have embedded the error message as comments
fn main() {
let mut owned: () = ();
let ref0: &() = &mut owned;
// ---------- mutable borrow occurs here
let ref1: &() = &owned;
// ^^^^^^ immutable borrow occurs here
drop(ref0);
// ---- mutable borrow later used here
}
归根结底,Rust 允许将 &mut
转换为 &
,但仅限于理论上。实际上,一旦您使用从可变借用创建的借用,同时有另一个常规借用,编译器突然意识到,转换后的借用仍然是可变借用。类型检查器在撒谎。
总之,不可能将 push() 和 last() 组合成一个函数。
P.S。如果 Rust 支持从 &mut
到 &
的真正转换,那会很好,将来不会产生上述错误。