gpt4 book ai didi

iterator - Iterator collect 的类型问题

转载 作者:行者123 更新时间:2023-11-29 08:21:09 29 4
gpt4 key购买 nike

我正在尝试转换 &str 的矢量对成一个 HashMap使用以下代码片段:

use std::collections::HashMap;

fn main() {
let pairs = vec!(("foo", "bar"), ("toto", "tata"));
let map: HashMap<&str, &str> = pairs.iter().collect();
println!("{:?}", map);
}

但是编译失败并出现此错误:

<anon>:5:47: 5:56 error: the trait `core::iter::FromIterator<&(&str, &str)>` is not implemented for the type `std::collections::hash::map::HashMap<&str, &str>` [E0277]
<anon>:5 let map: HashMap<&str, &str> = pairs.iter().collect();

但是,如果我添加 .cloned()打电话前 collect()一切正常:

...
let map: HashMap<&str, &str> = pairs.iter().cloned().collect();
...

即使我理解了错误信息(没有为类型 FromIterator<&(&str, &str)> 实现特征 HashMap<&str, &str> )我也不明白类型 &(&str, &str) 在哪里来自(根据 Rust 文档中的方法签名)以及为什么调用 cloned()解决了这个问题。

最佳答案

类型&(&str, &str)来自什么 iter() Vec 上返回:

fn iter(&self) -> Iter<T>

哪里 Iter<T> 工具 Iterator<Item=&T> :

impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T
...
}

换句话说,iter()在向量上返回一个迭代器,该迭代器产生对向量的引用。

cloned()解决了这个问题,因为它是一个转换 Iterator<Item=&T> 的迭代器适配器至 Iterator<Item=T>如果T是可克隆的。您可以将其视为 map(|v| v.clone()) 的简写。 :

let v1: Vec<i32> = vec![1, 2, 3, 4];
let v2: Vec<_> = v1.iter().cloned().collect();
let v3: Vec<_> = v1.iter().map(|v| v.clone()).collect();
assert_eq!(v2, v3);

碰巧(&str, &str)是可克隆的,因为每个元组组件也是可克隆的(所有引用都是),所以 cloned()将返回一个实现 Iterator<Item=(&str, &str)> 的对象- 到底是什么collect()需要创建一个 HashMap .

或者,您可以使用 into_iter()得到Iterator<Item=T>来自 Vec<T> , 但是原始向量将被消耗:

use std::collections::HashMap;

fn main() {
let pairs = vec!(("foo", "bar"), ("toto", "tata"));
let map: HashMap<&str, &str> = pairs.into_iter().collect();
println!("{:?}", map);
}

关于iterator - Iterator collect 的类型问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43404368/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com