我是一个Rust新手。我试图将有向图的邻接列表表示为char {vertex name}的HashMap到Vector of(char,int){vertex name,cost}。我希望最终的HashMap是不可变的,但是我想构建向量,然后不需要复制它以使其不可变。
我的代码如下。在指定的行我得到"不能借用不可变的解除引用(由于索引而取消引用是隐含的),因为它是可变的"。这是有道理的,因为Vec<(char,int)>在地图中是不可变的。但我不确定如何解决它。
有没有办法在Rust中执行此操作?
pub struct Edge {
to: char,
from: char,
weight: int
}
pub struct digraph {
_vertices: Vec<char>,
_adj_list: HashMap<char, Vec<(char,int)> >
}
impl digraph {
pub fn new(nodes: &Vec<char>, edges: &Vec<Edge> ) -> Option<digraph> {
let mut tmp_adj_list = HashMap::new();
for node in (*nodes).iter() {
tmp_adj_list.insert(*node, Vec::new());
}
for edge in (*edges).iter() {
let Edge{ to: to, from:from, weight:weight } = *edge;
if !(*nodes).contains(&to) | !(*nodes).contains(&from) {
return None;
}
tmp_adj_list[from].push((to,weight)) // *********** error here
}
Some(digraph { _vertices: (*nodes).clone(), _adj_list: tmp_adj_list })
}
}
答案 0 :(得分:8)
将[]
带到HashMap上是(现已弃用的)get(..)
函数的糖,声明为:
fn get<'a>(&'a self, k: &K) -> &'a V
并返回一个常量(&
)引用。但是Vec的push(..)
方法需要&mut
引用,因此错误。
您需要的是HashMap的get_mut(..)
方法,该方法返回对该值的&mut
引用。
另外,一些小问题:
(*foo).bar()
与foo.bar()
完全相同for &edge in edges.iter() {...}
包括所有这些,你的功能变为:
impl digraph {
pub fn new(nodes: &Vec<char>, edges: &Vec<Edge> ) -> Option<digraph> {
let mut tmp_adj_list = HashMap::new();
for &node in nodes.iter() {
tmp_adj_list.insert(node, Vec::new());
}
for &edge in edges.iter() {
let Edge{ to: to, from:from, weight:weight } = edge;
if !nodes.contains(&to) | !nodes.contains(&from) {
return None;
}
tmp_adj_list.get_mut(&from).push((to,weight))
}
Some(digraph { _vertices: nodes.clone(), _adj_list: tmp_adj_list })
}
}