在 Rust 中使用结构创建哈希图

car*_*aez 2 rust

我正在尝试在 rust 中设置对象/结构的哈希图......但我不明白这个具体问题(终身错误)。

#[derive(Hash, Eq, PartialEq)]
#[derive(Serialize, Deserialize, Debug)]
pub struct Node<'a> {
    identifier: &'a str,
    sha_id: Vec<u8>,
    successor_id: Option<Vec<u8>>,
    predecessor_id: Option<Vec<u8>>,
}


impl<'a> Node<'a> {
    ...
    ..
    .
}

pub struct Application<'a> {
    hash_map: HashMap<&'a str, Node>,
}

impl<'a> Application<'a> {
    fn join(&self, node: &Node) {
        self.hash_map.insert(node.identifier, node);
    }
}
Run Code Online (Sandbox Code Playgroud)

错误是缺少生命周期说明符hash_map: HashMap<&'a str, Node>,我试图解决将 Node 更改为 Node<'a> 的问题,但是当我尝试插入时它会引发“类型不匹配”错误...

我不知道为什么我有这个问题错过了整个生命周期而且我没有找到解决方案..

更新:

#[derive(Hash, Eq, PartialEq)]
#[derive(Serialize, Deserialize, Debug)]
pub struct Node<'a> {
    identifier: &'a str,
    sha_id: Vec<u8>,
    successor_id: Option<Vec<u8>>,
    predecessor_id: Option<Vec<u8>>,
}


impl<'a> Node<'a> {
    ...
    ..
    .
}

pub struct Application<'a> {
    hash_map: HashMap<&'a str, Node<'a>>,
}

impl<'a> Application<'a> {
    fn join(&self, node: &Node) {
        self.hash_map.insert(node.identifier, *node);
    }
}
Run Code Online (Sandbox Code Playgroud)

输出是:

"explicit lifetime required in the type of `node`"
Run Code Online (Sandbox Code Playgroud)

更新2:

pub struct Application<'a> {
    hash_map: HashMap<&'a str, Node<'a>>,
}

impl<'a> Application<'a> {
    fn join(&mut self, node: &'a Node<'a>) {
        self.hash_map.insert(node.identifier, *node);
    }

}
Run Code Online (Sandbox Code Playgroud)

输出是:

self.hash_map.insert(node.identifier, *node); cannot move out of borrowed content
Run Code Online (Sandbox Code Playgroud)

完整的解决方案

#[derive(Clone, Hash, Eq, PartialEq)]
#[derive(Serialize, Deserialize, Debug)]
pub struct Node<'a> {
    identifier: &'a str,
    sha_id: Vec<u8>,
    successor_id: Option<Vec<u8>>,
    predecessor_id: Option<Vec<u8>>,
}


impl<'a> Node<'a> {
...
..
.
}

pub struct Application<'a> {
    hash_map: HashMap<&'a str, Node<'a>>,
}

impl<'a> Application<'a> {
    fn join(&mut self, node: Node<'a>) {
        self.hash_map.insert(node.identifier, node);
    }

}
Run Code Online (Sandbox Code Playgroud)

For*_*Bru 5

这个简化的例子似乎有效:

use std::collections::HashMap;

#[derive(Clone)] // we'll be cloning it later on
struct Node<'a> {
    data: &'a i32 
}


struct Test<'a> {
    hash_map: HashMap<&'a str, Node<'a>>  // the hash map owns the struct
}

impl<'a> Test<'a> {
    fn new() -> Test<'a> {
        Test {hash_map: HashMap::new()}
    }

    fn join(
        &mut self, // must be mutable
        node: Node<'a>) { // do not pass a reference
        self.hash_map.insert("test", node);  // inserting moves `node`
    }
}

fn main() {
    let stuff = Node {data: &12};
    let mut test = Test::new();

    test.join(stuff.clone());  // if we don't clone, `stuff` will get moved

    println!("{}", *test.hash_map["test"].data);  // outputs "12"
}
Run Code Online (Sandbox Code Playgroud)

由于std::collections::HashMap::insert尝试移动它的第二个参数,因此不能取消引用指向某物的指针并将其传递给此方法,否则指针将变为未初始化,这是不允许的。解决这个问题的一种方法是传递一个移动的值而不是一个指向join.

  • 虽然您的代码片段可能会回答这个问题,但如果您可以添加几句话,哪里出了问题以及您如何解决它,最好是提供一些指向文档或类似问题的链接。 (2认同)