不能借用可变的变量,因为在构建自引用HashMap时也借用了不可变的变量 [英] cannot borrow variable as mutable because it is also borrowed as immutable while building a self-referential HashMap
问题描述
我正在尝试构建自引用HashMap
:
I'm trying to build a self-referential HashMap
:
use std::collections::HashMap;
struct Node<'a> {
byte: u8,
map: HashMap<i32, &'a Node<'a>>,
}
fn main() {
let mut network = HashMap::<u32, Node>::new();
network.insert(0, Node { byte: 0, map: HashMap::<i32, &Node>::new() });
network.insert(1, Node { byte: 1, map: HashMap::<i32, &Node>::new() });
let zeroeth_node = network.get(&0).unwrap();
let mut first_node = network.get_mut(&1).unwrap();
first_node.map.insert(-1, zeroeth_node);
}
我遇到了借用检查器错误,但我不明白其原因-是我更新错误的HashMap
的方法,还是我的自引用用法?
I'm running into a borrow-checker error, but I don't understand its source -- is it my method of updating the HashMap
that is wrong, or my self-referential usage of it?
错误:
<anon>:15:26: 15:33 error: cannot borrow `network` as mutable because it is also borrowed as immutable [E0502]
<anon>:15 let mut first_node = network.get_mut(&1).unwrap();
^~~~~~~
<anon>:14:24: 14:31 note: previous borrow of `network` occurs here; the immutable borrow prevents subsequent moves or mutable borrows of `network` until the borrow ends
<anon>:14 let zeroeth_node = network.get(&0).unwrap();
^~~~~~~
<anon>:18:2: 18:2 note: previous borrow ends here
<anon>:8 fn main() {
...
<anon>:18 }
^
推荐答案
答案
这些类型的结构在Rust中很难制造.您的样本中缺少的主要内容是使用 RefCell
允许共享引用. RefCell
将Rust的借位检查从编译时移至运行时,从而使您可以在内存位置中传递.但是,不要在任何地方都开始使用RefCell
,因为它仅适用于此类情况,如果您试图以可变方式借用某些东西而又已经以可变方式借用了某些内容,则RefCell
会导致您的程序进入panic!
.这仅适用于在network
中创建的Node
.您将无法创建仅存在于单个Node
内部的Node
.
Answer
These types of structures can be hard to make in Rust. The main thing missing from your sample is the use of RefCell
which allows for shared references. RefCell
s move Rust's borrow checking from compile-time to run-time, and thus allows you to pass around the memory location. However, don't start using RefCell
everywhere, as it is only suitable for situations like this, and RefCell
s will cause your program to panic!
if you attempt to mutably borrow something while it is already mutably borrowed. This will only work with Node
s created in network
; you won't be able to create Node
s that exist purely inside of a single Node
.
use std::collections::HashMap;
use std::cell::RefCell;
#[derive(Debug)]
struct Node<'a> {
byte: u8,
map: HashMap<i32, &'a RefCell<Node<'a>>>,
}
fn main() {
let mut network = HashMap::new();
network.insert(0, RefCell::new(Node { byte: 0, map: HashMap::new() }));
network.insert(1, RefCell::new(Node { byte: 1, map: HashMap::new() }));
let zero_node = network.get(&0).unwrap();
zero_node.borrow_mut().byte = 2;
let first_node = network.get(&1).unwrap();
first_node.borrow_mut().map.insert(-1, zero_node);
println!("{:#?}", network);
}
这篇关于不能借用可变的变量,因为在构建自引用HashMap时也借用了不可变的变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!