简体   繁体   English

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

[英]Creation of a hashmap with struct in Rust

I am trying to set up a hashmap of objects / structs in rust... But I don't understand this concrete problem (a lifetime error). 我正在尝试在锈中建立对象/结构的哈希表...但是我不明白这个具体问题(生命周期错误)。

#[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);
    }
}

The error is a missing lifetime specifier in the hash_map: HashMap<&'a str, Node> that I tried to solve changing Node to Node<'a> but It throws a "mismatched type" error when I try to insert... 该错误是hash_map: HashMap<&'a str, Node>缺少生命周期说明符hash_map: HashMap<&'a str, Node> ,我试图解决将Node更改为Node <'a>的问题,但是当我尝试插入时会引发“不匹配类型”错误。

I don't exactly why I have this problem missing the lifetime and I don't find solutions.. 我不完全是为什么我会错过这个问题,而我找不到解决办法。

UPDATE: 更新:

#[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);
    }
}

And the output is: 输出为:

"explicit lifetime required in the type of `node`"

UPDATE2: UPDATE2:

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

}

And the output is: 输出为:

self.hash_map.insert(node.identifier, *node); cannot move out of borrowed content

COMPLETE SOLUTION 完整的解决方案

#[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);
    }

}

This simplified example seems to work: 这个简化的示例似乎有效:

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"
}

Since std::collections::HashMap::insert attempts to move its second argument, one can't dereference a pointer to something and pass that to this method because otherwise the pointer will become uninitialized, which isn't permitted. 由于std::collections::HashMap::insert尝试移动其第二个参数,因此无法取消引用某个对象的指针并将其传递给此方法,因为否则该指针将变为未初始化的状态,这是不允许的。 A way so solve this is to pass a moved value and not a pointer to join . 解决此问题的一种方法是传递移动的值,而不是传递要join的指针。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM