我正在为一个 struct 体写一个方法,它的成员是Vec
.我想写的函数remove_thing
应该引用Vec
中的一个元素并删除它,其余部分留在原位.
我得到了一个借位判断器错误,我不能borrow Vec
作为可变的,因为我有一个借位的元素是不可变的.我的期望是,仍然有一个有效的方式来表达这一点,因为我实际上并没有改变内部元素,只是改变包含Vec
.但我可能错了.
下面是一个简短的复制:
struct Thing {
name: String,
data: String,
}
struct HasSomeThings {
things: Vec<Thing>,
}
impl HasSomeThings {
fn thing_by_name(&self, name: &str) -> Option<&Thing> {
for t in self.things.iter() {
if t.name == name {
return Some(&t);
}
}
None
}
// Is it impossible to implement this function?
// It seems having a reference to a Thing in the vector prevents
// you from removing it from that vector.
fn remove_thing(&mut self, thing: &Thing) {
self.things.retain(|t| t.name != thing.name);
}
}
fn main() {
// Imagine this comes from reading a file somewhere
let mut some_things = HasSomeThings {
things: vec![
Thing { name: "one".to_string(), data: "one data".to_string() },
Thing { name: "two".to_string(), data: "two data".to_string() },
Thing { name: "three".to_string(), data: "three data".to_string() },
]
};
// Imagine this comes from user input
let name = "one";
let one_thing = some_things.thing_by_name(name).unwrap();
println!("{}", one_thing.data);
some_things.remove_thing(one_thing);
}
我看到的错误是:
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `some_things` as mutable because it is also borrowed as immutable
--> src/main.rs:44:5
|
41 | let one_thing = some_things.thing_by_name(name).unwrap();
| ----------- immutable borrow occurs here
...
44 | some_things.remove_thing(one_thing);
| ^^^^^^^^^^^^------------^^^^^^^^^^^
| | |
| | immutable borrow later used by call
| mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `playground` (bin "playground") due to 1 previous error
有没有一些技巧可以实现remove_thing
函数?或者,有没有合理的方法来重组我的代码,以便我可以使用引用Vec
中的元素,然后再删除它?我是否只需要从头开始重建整个HasSomeThings
实例?