代码之家  ›  专栏  ›  技术社区  ›  Paul Chernoch

如何匹配和修改Vec<Option<HashSet>>中的元素?

  •  0
  • Paul Chernoch  · 技术社区  · 5 年前

    我有一个 Vec 可选的 HashSet None ,我想分配一个 哈希集 把它储存在 . 在这两种情况下,我想补充一下 哈希集

    我知道编译器的错误在抱怨什么,但不知道什么语法会使问题消失。编译器建议的更改也无法编译,以及我尝试的任何其他语法。如何匹配 Vec公司 手机,看看是不是 ,分配 Some<HashSet> 如果是的话 或者直接访问 哈希集 如果它确实存在,并且在这两种情况下都向集合中添加一个新的整数?

    use std::collections::HashSet;
    use std::collections::BTreeSet;
    use std::iter::FromIterator;
    use maplit;
    
    pub struct Graph {
        outgoing_edges : Vec<Option<HashSet<usize>>>,
        incoming_edges : Vec<Option<HashSet<usize>>>
    }
    
    impl Graph {
        pub fn new(node_count : usize) -> Self {
            Graph {
                outgoing_edges : vec!(None; node_count),
                incoming_edges : vec!(None; node_count)
            }
        }
    
        /// Add a directional edge that starts at `from_node` and points to `to_node`.
        pub fn add_edge(&mut self, from_node : usize, to_node : usize) {
            match &self.outgoing_edges[from_node] {
                Some(mut set) => { set.insert(to_node); () },
                None => { self.outgoing_edges[from_node] = Some(hashset!{ to_node }); () }
            }
            match &self.incoming_edges[to_node] {
                Some(mut set) => { set.insert(from_node); () },
                None => { self.incoming_edges[to_node] = Some(hashset!{ from_node }); () }
            }
        }
    }
    

    错误:

    (行号来自我的原始文件,而不是简短的代码片段。错误消息来自我添加和号以借用之前的信息,如上图所示,但代码更改没有起作用。)

    error[E0507]: cannot move out of index of `std::vec::Vec<std::option::Option<std::collections::HashSet<usize>>>`
      --> src\graph\mod.rs:46:15
       |
    46 |         match self.outgoing_edges[from_node] {
       |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider borrowing here: `&self.outgoing_edges[from_node]`
    47 |             Some(mut set) => { set.insert(to_node); () },
       |                  -------
       |                  |
       |                  data moved here
       |                  move occurs because `set` has type `std::collections::HashSet<usize>`, which does not implement the `Copy` trait
    
    1 回复  |  直到 5 年前
        1
  •  2
  •   edwardw Neil Bartlett    5 年前

    这很简单,您需要通过引用绑定:

    /// Add a directional edge that starts at `from_node` and points to `to_node`.
    pub fn add_edge(&mut self, from_node : usize, to_node : usize) {
        match self.outgoing_edges[from_node] {
            Some(ref mut set) => { set.insert(to_node); },
            None => { self.outgoing_edges[from_node] = Some(hashset!{ to_node }); }
        }
        match self.incoming_edges[to_node] {
            Some(ref mut set) => { set.insert(from_node); },
            None => { self.incoming_edges[to_node] = Some(hashset!{ from_node }); }
        }
    }
    

    或者与人体工程学特征相匹配 binding mode

    /// Add a directional edge that starts at `from_node` and points to `to_node`.
    pub fn add_edge(&mut self, from_node : usize, to_node : usize) {
        match &mut self.outgoing_edges[from_node] {
            Some(set) => { set.insert(to_node); },
            None => { self.outgoing_edges[from_node] = Some(hashset!{ to_node }); }
        }
        match &mut self.incoming_edges[to_node] {
            Some(set) => { set.insert(from_node); },
            None => { self.incoming_edges[to_node] = Some(hashset!{ from_node }); }
        }
    }
    
        2
  •  3
  •   Sven Marnach    5 年前

    您可以使用该方法,而不是使用模式匹配 Option::get_or_insert_with() 创建一个新的哈希集(如果需要),并返回对现有哈希集或新创建的哈希集的引用。完整代码可以如下所示:

    pub fn add_edge(&mut self, from_node: usize, to_node: usize) {
        self.outgoing_edges[from_node]
            .get_or_insert_with(HashSet::new)
            .insert(to_node);
        self.incoming_edges[to_node]
            .get_or_insert_with(HashSet::new)
            .insert(from_node);
    }