我正在尝试构建一个自引用的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
错误的方法,还是我对它的自我引用? / p>
错误:
<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 }
^
答案 0 :(得分:2)
这些类型的结构在Rust中很难制作。您的示例中缺少的主要内容是使用允许共享引用的RefCell
。 RefCell
将Rust的借用检查从编译时移动到运行时,从而允许您传递内存位置。但是,请勿在任何地方开始使用RefCell
,因为它仅适用于此类情况,RefCell
s会导致您的程序panic!
,如果您尝试可变地借用某些内容已经可以借来了。这仅适用于Node
中创建的network
;您将无法创建纯粹存在于单个Node
内的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);
}