簡體   English   中英

在結構中存儲 HashMap 的迭代器

[英]Storing an iterator for a HashMap in a struct

編輯

從建議的解決方案看來,我試圖實現的目標似乎是不可能的/不是正確的方法,因此 - 我將在這里解釋最終目標:

我正在使用 serde 從 YAML 文件中解析 Foo 的值,我想讓用戶一次從 yaml 中獲取其中一個存儲值,這就是為什么我想在我的結構中存儲一個迭代器


我有兩個類似於以下的結構:

struct Bar {
    name: String,
    id: u32
}

struct Foo {
    my_map: HashMap<String, Bar>
}

在我的Foo結構中,我希望將一個迭代器存儲到我的 HashMap 中,以便用戶可以根據需要從我的 map 中借用值。 從理論上講,完整的 Foo class 看起來像:

struct Foo {
    my_map: HashMap<String, Bar>,
    my_map_iter: HashMap<String, Bar>::iterator
}

impl Foo {
    fn get_pair(&self) -> Option<(String, Bar)> {
        // impl...
    }
}

但無論我嘗試什么,我似乎都無法將它拉下來並創建這樣一個變量(各種編譯錯誤,似乎我只是試圖做錯)。

如果有人能指出我實現這一目標的正確方法,並且如果有更好的方法來實現我正在嘗試做的事情,我會很高興 - 我想知道這一點。

謝謝!

我正在使用 serde 從 YAML 文件中解析 Foo 的值

解析它們時,您應該將值放在Vec而不是HashMap中。

我想您的值也有名稱,這就是為什么您認為HashMap會很好。 您可以像這樣存儲它們:

let parsed = vec![]

for _ in 0..n_to_parse {
    // first item of the tuple is the name second is the value
    let key_value = ("Get from", "serde");
    parsed.push(key_value);
}

然后,一旦您像這樣存儲它,就可以通過跟蹤當前索引輕松地從中獲取對:

struct ParsedHolder {
    parsed: Vec<(String, String)>,
    current_idx: usize,
}

impl ParsedHolder {
    fn new(parsed: Vec<(String, String)>) -> Self {
        ParsedHolder {
            parsed,
            current_idx: 0,
        }
    }

    fn get_pair(&mut self) -> Option<&(String, String)> {
        if let Some(pair) = self.parsed.get(self.current_idx) {
            self.current_idx += 1;
            Some(pair)

        } else {
            self.current_idx = 0;
            None
        }
    }
}

現在這可以通過使用VecDeque進一步改進,這將允許您有效地取出 parsed 的第一個元素。 這將使不使用克隆變得容易。 但是這樣一來,您將只能通過所有已解析的值 go 一次,我認為這實際上是您在用例中想要的。

但我會讓你實現VecDeque

這很難的原因是,除非我們確保HashMap在我們迭代時沒有發生突變,否則我們可能會遇到一些麻煩。 為了確保HashMap在迭代器存在之前是不可變的:

use std::collections::HashMap;
use std::collections::hash_map::Iter;

struct Foo<'a> {
    my_map: &'a HashMap<u8, u8>,
    iterator: Iter<'a, u8, u8>,
}

fn main() {
    let my_map = HashMap::new();
    let iterator = my_map.iter();

    let f = Foo {
        my_map: &my_map,
        iterator: iterator,
    };
}

如果您可以確定或知道HashMap不會從中刪除新鍵或鍵(使用現有鍵編輯值很好),那么您可以這樣做:

struct Foo {
    my_map: HashMap<String, String>,
    current_idx: usize,
}

impl Foo {
    fn new(my_map: HashMap<String, String>) -> Self {
        Foo {
            my_map,
            current_idx: 0,
        }
    }

    fn get_pair(&mut self) -> Option<(&String, &String)> {
        if let Some(pair) = self.my_map.iter().skip(self.current_idx).next() {
            self.current_idx += 1;
            Some(pair)

        } else {
            self.current_idx = 0;
            None
        }
    }

    fn get_pair_cloned(&mut self) -> Option<(String, String)> {
        if let Some(pair) = self.my_map.iter().skip(self.current_idx).next() {
            self.current_idx += 1;
            Some((pair.0.clone(), pair.1.clone()))

        } else {
            self.current_idx = 0;
            None
        }
    }
}

但是這相當低效,因為我們每次都需要遍歷鍵以找到下一個鍵。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM