![](/img/trans.png)
[英]Rust - create hashmap which uses part of the data it's storing from an iterator
[英]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.