问题描述
每次使用 Rust 时,我都会遇到与所有权/借用相关的类似问题,所以这里是最简单的一段代码来说明我经常遇到的问题:
I run into similar problems related to ownership/borrowing every time I use Rust, so here is the simplest piece of code that illustrates my usual problems:
use std::cell::RefCell;
struct Res {
name: String,
}
impl Res {
fn new(name: &str) -> Res {
Res {
name: name.to_string(),
}
}
// I don't need all_res to be mutable
fn normalize(&mut self, all_res: &Vec<Res>) {
// [...] Iterate through all_res and update self.name
self.name = "foo".to_string();
}
}
fn main() {
let res = RefCell::new(vec![Res::new("res1"), Res::new("res2")]);
for r in res.borrow_mut().iter_mut() {
// This panics at runtime saying it's
// already borrowed (which makes sense, I guess).
r.normalize(&*res.borrow());
}
}
阅读RefCell
我认为这会奏效.它可以编译,但在运行时会发生恐慌.
After reading about RefCell
I thought this would work. It compiles, but panics at runtime.
如何在迭代同一个向量时引用一个向量?有没有更好的数据结构可以让我这样做?
How do I reference a vector while iterating over the same vector? Is there any better data structure to allow me to do this?
推荐答案
您的程序出现混乱,因为您试图同时可变且不可变地借用 Vec
:这是不允许的.
Your program panics because you're trying to borrow the Vec
mutably and immutably at the same time: this is not allowed.
您需要做的是仅将 String
包装在 RefCell
中.这允许您在迭代 Vec
时改变字符串.
What you need to do instead is wrap only the String
s in RefCell
. This allows you to mutate the strings while iterating the Vec
.
use std::cell::RefCell;
struct Res {
name: RefCell<String>,
}
impl Res {
fn new(name: &str) -> Res {
Res {
name: RefCell::new(name.to_string()),
}
}
// I don't need all_res to be mutable
fn normalize(&self, all_res: &Vec<Res>) {
// [...] Iterate through all_res and update self.name
*self.name.borrow_mut() = "foo".to_string();
}
}
fn main() {
let res = vec![Res::new("res1"), Res::new("res2")];
for r in res.iter() {
r.normalize(&res);
}
println!("{}", *res[0].name.borrow());
}
这篇关于可变借用后的不可变引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!