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



我有一个可选HashSets的Vec。如果插槽None,我想分配一个HashSet并将其存储在Vec中。 在这两种情况下,我都想添加到HashSet.

我了解编译器错误在抱怨什么,但不了解什么语法会使问题消失。编译器建议的更改也无法编译,以及我尝试的任何其他语法。如何匹配Vec单元格,检查它是否None,如果None则分配Some<HashSet>,或者如果确实存在,则仅访问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>>>`
--> srcgraphmod.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

如果需要,可以使用方法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);
}

这非常简单,您希望通过引用绑定:

/// 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 }); }
}
}

或者使用称为绑定模式的图案匹配人体工程学功能,您还可以执行以下操作:

/// 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 }); }
}
}

最新更新