我们有一个 HashMap,我们对其进行迭代和映射以替换值,但是遇到了一个问题,将其收集回具有不同值类型的新 HashMap。
value of type `std::collections::HashMap<std::string::String, std::string::String>`
cannot be built from `std::iter::Iterator<Item=(&std::string::String, std::string::String)>`
我们所做的基本上归结为:let old: HashMap<String, Value> = some_origin();
let new: HashMap<String, String> = old.iter().map(|(key, value)| {
return (key, some_conversion(value));
}).collect();
如果对两个迭代器进行压缩,例如,也会返回相同的迭代器类型(并且不可收集)。在这种情况下,压缩键,以及仅返回转换值的映射。new = old.keys().into_iter().zip(old.iter().map(|(key, value)| some_conversion(value)).collect();
最佳答案
问题是iter()
( docs ) 返回一个“非消耗”迭代器,它分发对基础值 ([1]) 的引用。新款HashMap
不能使用引用( &String
)构造,它需要值( String
)。
在您的示例中,some_conversion
似乎返回一个新的 String
对于值(value)部分,因此应用 .clone()
到关键会做的伎俩:
let old: HashMap<String, Value> = some_origin();
let new: HashMap<String, String> = old.iter().map(|(key, value)| {
return (key.clone(), some_conversion(value));
// ^---- .clone() call inserted
}).collect();
Here是 Rust 游乐场上完整示例的链接。看编译器的错误信息[2],这确实很难弄清楚。我认为对此最有帮助的是在 Rust 中建立关于引用和所有权的直觉,以了解何时引用是可以的以及何时需要拥有的值。
虽然我建议阅读 Rust Book 中关于引用和所有权的部分,甚至更多的 Programming Rust,但要点如下:
Rc
)。 Copy
”类型,它们的复制成本很低,例如 i32
)。 这有什么帮助?
我希望这能提供一些直觉(我再次真正推荐 Rust 编程)。一般来说,如果你做某事具有值(value),你要么拥有它的所有权,要么得到一个引用。如果您取得所有权,则无法再使用拥有所有权的原始变量。如果您获得引用,则不能将所有权交给其他人(无需克隆)。而 Rust 不会为你克隆。
[1]:文档称其为“以任意顺序访问所有键值对的迭代器。迭代器元素类型为 (&'a K, &'a V)”。忽略
'a
生命周期参数,可以看到元素类型为(&K, &V)
.[2]:
13 | .collect();
| ^^^^^^^ value of type `std::collections::HashMap<std::string::String, std::string::String>` cannot be built from `std::iter::Iterator<Item=(&std::string::String, std::string::String)>`
|
= help: the trait `std::iter::FromIterator<(&std::string::String, std::string::String)>` is not implemented for `std::collections::HashMap<std::string::String, std::string::String>`
关于Rust 从迭代器中收集 HashMap ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63173420/