Создание хеш-карты со структурой в Rust - PullRequest
0 голосов
/ 04 января 2019

Я пытаюсь настроить хэш-карту объектов / структур из ржавчины ... Но я не понимаю эту конкретную проблему (пожизненная ошибка).

#[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>, который я пытался решить, меняя узел на Node <'a>, но он выдает ошибку "несоответствующий тип" при попытке вставить ...

Я не совсем понимаю, почему у меня эта проблема пропущена, и я не нахожу решения ..

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

И вывод:

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

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

}

И вывод:

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 Ответ

0 голосов
/ 04 января 2019

Этот упрощенный пример работает:

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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...