【发布时间】:2021-05-19 00:02:02
【问题描述】:
我正在尝试存储对可变向量元素的引用以供以后使用。但是,一旦我改变了向量,我就不能再使用存储的引用了。我知道这是因为借用对元素的引用也需要借用对向量本身的引用。因此,向量不能被修改,因为这将需要借用一个可变引用,当另一个对向量的引用已经被借用时,这是不允许的。
这是一个简单的例子
struct Person {
name: String,
}
fn main() {
// Create a mutable vector
let mut people: Vec<Person> = ["Joe", "Shavawn", "Katie"]
.iter()
.map(|&s| Person {
name: s.to_string(),
})
.collect();
// Borrow a reference to an element
let person_ref = &people[0];
// Mutate the vector
let new_person = Person {
name: "Tim".to_string(),
};
people.push(new_person);
// Attempt to use the borrowed reference
assert!(person_ref.name == "Joe");
}
产生以下错误
error[E0502]: cannot borrow `people` as mutable because it is also borrowed as immutable
--> src/main.rs:21:5
|
15 | let person_ref = &people[0];
| ------ immutable borrow occurs here
...
21 | people.push(new_person);
| ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
24 | assert!(person_ref.name == "Joe");
| --------------- immutable borrow later used here
我也尝试按照here 的建议对矢量元素进行装箱,但这无济于事。我认为它可能允许我删除对向量的引用,同时保持对元素的引用,但显然不是。
struct Person {
name: String,
}
fn main() {
// Create a mutable vector
let mut people: Vec<Box<Person>> = ["Joe", "Shavawn", "Katie"]
.iter()
.map(|&s| {
Box::new(Person {
name: s.to_string(),
})
})
.collect();
// Borrow a reference to an element
let person_ref = people[0].as_ref();
// Mutate the vector
let new_person = Box::new(Person {
name: "Tim".to_string(),
});
people.push(new_person);
// Attempt to use the borrowed reference
assert!(person_ref.name == "Joe");
}
这仍然会产生同样的错误
error[E0502]: cannot borrow `people` as mutable because it is also borrowed as immutable
--> src/main.rs:23:5
|
17 | let person_ref = people[0].as_ref();
| ------ immutable borrow occurs here
...
23 | people.push(new_person);
| ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
...
26 | assert!(person_ref.name == "Joe");
| --------------- immutable borrow later used here
有没有办法做到这一点,还是我试图做一些不可能的事情?
【问题讨论】:
-
这是一个理论还是现实世界的例子?原因是,由于使用
assert!(people[0].name == "Joe");的选项被隐式丢弃,因此不清楚这个问题是理论上的,还是现实世界中的一个更大的图景阻止了提到的解决方案。 -
@Marcus - 我不确定你的意思是“使用...的选项被隐式丢弃”。这只是尝试访问
people[0].name的一种方式。这个问题确实来自一个真实世界的示例,该示例尝试在循环中填充可变向量,同时在哈希映射中存储对元素的引用。 Context. -
上下文澄清了一切 :) 我认为在这种情况下,没有比您的答案更好的解决方案了,因为一个参考可能超出范围。
标签: rust reference borrow-checker borrowing