在 Rust 中从 rendezvous_hash::RendezvousNodes 中删除一个节点

Removing a node from rendezvous_hash::RendezvousNodes in Rust

我正在尝试从 rendezvous_hash crate 的 RendezvousNodes 集合中删除一个节点。

我使用的简化示例代码是:

use std::collections::HashMap;
use rendezvous_hash::{RendezvousNodes, Node};
use rendezvous_hash::{WeightedNode, Capacity};

fn main() {
    let mut nodes = RendezvousNodes::default();


    let node1 = WeightedNode::new("foo", Capacity::new(70.0).unwrap());
    nodes.insert(node1);
    println!("{}", nodes.len());

    for node in nodes.iter() {
        println!("{}", node.node_id());
    }

    nodes.remove(node1.node_id());
    println!("{}", nodes.len());
}

由于移动后借用了价值,这失败了。

error[E0382]: borrow of moved value: `node1`
  --> src/main.rs:17:18
   |
9  |     let node1 = WeightedNode::new("foo", Capacity::new(70.0).unwrap());
   |         ----- move occurs because `node1` has type `WeightedNode<&str>`, which does not implement the `Copy` trait
10 |     nodes.insert(node1);
   |                  ----- value moved here
...
17 |     nodes.remove(node1.node_id());
   |                  ^^^^^ value borrowed here after move

传递节点工作的参考:

...
    nodes.insert(&node1);
...

但是,现在我必须自己跟踪我不想要的节点值,这可能会在以后造成范围和生命周期方面的问题。 让 nodes 集合跟踪其节点就足够了。

有没有办法删除节点,尽管它现在由节点拥有,或者这是板条箱的问题?

通过阅读 remove 方法的源代码:

/// Removes the specified node from the candidates.
    ///
    /// If the node does not exist, this method will return `None`.
    pub fn remove<M>(&mut self, node_id: &M) -> Option<N>
    where
        N::NodeId: Borrow<M>,
        M: PartialEq,
    {
        if let Some(i) = self
            .nodes
            .iter()
            .position(|n| n.node_id().borrow() == node_id)
        {
            Some(self.nodes.swap_remove(i))
        } else {
            None
        }
    }

来自

docs.rs

很明显,传递对 node_id 的引用就可以了。

nodes.remove(&"foo");

编辑:

如果我更彻底地阅读文档,我可能会发现:

// Update the node set.
// (The relative order between existing nodes are preserved)
nodes.remove(&"baz");