rust - 如何获取 HashMap 中的值以相互引用?
问题描述
我正在尝试通过为COOL编写编译器来自学 Rust 。
我有一个HashMap
按名称存储多个节点的。我还希望每个节点都引用其父节点(如果有的话)。这样,我既可以按名称查找节点,也可以在恒定时间内将树从子节点导航到父节点。
在此示例中,我希望命名B
为引用的节点A
#![allow(unused_variables)]
#![allow(dead_code)]
use std::collections::HashMap;
struct Node {
name: String,
parent_name: Option<String>,
parent: Option<&'static Node>, // I'm not sure this is the correct lifetime
}
fn main() {
let mut hm: HashMap<String, Node> = HashMap::new();
hm.insert(
"A".to_string(),
Node {
name: "A".to_string(),
parent_name: None,
parent: None,
},
);
hm.insert(
"B".to_string(),
Node {
name: "B".to_string(),
parent_name: Some("A".to_string()),
parent: None,
},
);
// ---------------
// This is where things go awry.
let a: &Node = hm.get(&"A".to_string()).unwrap();
let b: &mut Node = hm.get_mut(&"B".to_string()).unwrap();
b.parent = Some(a);
}
无论我如何更改代码,我都会根据多个引用和/或生命周期问题得到错误。有没有办法在 Rust 中做到这一点?
解决方案
可以使用Rc让父节点同时为 HashMap 和子节点所有,使用RefCell可以让你改变不可变引用的数据,这样你就不必同时借用hm
可变和不可变。
#![allow(unused_variables)]
#![allow(dead_code)]
use std::collections::HashMap;
use std::rc::Rc;
use std::cell::RefCell;
struct Node {
name: String,
parent_name: Option<String>,
parent: Option<Rc<RefCell<Node>>>, // use Rc to enable multiple ownership
}
fn main() {
let mut hm: HashMap<String, Rc<RefCell<Node>>> = HashMap::new();
hm.insert(
"A".to_string(),
Rc::new(RefCell::new(Node {
name: "A".to_string(),
parent_name: None,
parent: None,
})),
);
hm.insert(
"B".to_string(),
Rc::new(RefCell::new(Node {
name: "B".to_string(),
parent_name: Some("A".to_string()),
parent: None,
})),
);
let a: &Rc<RefCell<Node>> = hm.get(&"A".to_string()).unwrap();
let b: &Rc<RefCell<Node>> = hm.get(&"B".to_string()).unwrap();
// Can't borrow hm as mutable and immutable at the same time
// use RefCell to mutate data even when there are immutable references to that data
b.borrow_mut().parent = Some(Rc::clone(a));
}
推荐阅读
- android - 在 Main Activity 中使用 google drive api 类助手
- kotlin - 当我使用 find() 创建视图并在模式窗口中打开它时 UI 冻结
- reactjs - 仅将 css bootstrap 用于手风琴
- javascript - 从字符串中解析一个 RegEx 数组
- docker - IBM MQ 容器无法启动
- python - 按分钟在 FB Prophet 中进行预测
- java - 在写入文件时移动文件是否是线程安全的?
- code-metrics - 如何使用 switch 语句获得低圈复杂度?
- macos - 强制 Filewave 验证
- java - Java中DataTables的服务器端处理