如何在Rust中构建向量的HashMap?

use*_*510 4 rust

我是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 })
    }
}
Run Code Online (Sandbox Code Playgroud)

Lev*_*ans 8

取[]到一个HashMap是糖的(废弃)get(..)函数,该函数的声明为:

fn get<'a>(&'a self, k: &K) -> &'a V
Run Code Online (Sandbox Code Playgroud)

并返回一个constant(&)引用.但push(..)Vec 的方法需要&mut参考,因此错误.

你需要的是get_mut(..)HashMap 的方法,它返回&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 })
    }
}
Run Code Online (Sandbox Code Playgroud)