代码之家  ›  专栏  ›  技术社区  ›  carlos.baez

用Rust中的结构创建hashmap

  •  -2
  • carlos.baez  · 技术社区  · 6 年前

    我正试图建立一个生锈的对象/结构的哈希图…但我不理解这个具体的问题(终生错误)。

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

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

    我不明白为什么我会有这个问题错过一生,我也找不到解决办法。

    更新:

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

    输出为:

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

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

    输出为:

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

    完整的解决方案

    #[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);
        }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   ForceBru    6 年前

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

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

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