我正在尝试从Vec<BTreeSet<char>>
创建一个集合(Vec<Vec<char>>
)的向量。到目前为止,这是我的进展:
use std::collections::BTreeSet;
fn main() {
// The data
let transaction_list = [
vec!['A','B','C','D'],
vec!['B','B','C'],
vec!['A','B','B','D']
];
// Successfully created a set from the Vec of Vec. It contains unique chars
let item_set: BTreeSet<char> = transaction_list.iter().flat_map(|t| t).cloned().collect();
// Made the same Vec of Vec. Basically just experimenting with map and collect
let the_same_transaction_list: Vec<Vec<char>> = transaction_list.iter().map(|t| t ).cloned().collect::<Vec<_>>();
// ERROR
let transaction_set: Vec<BTreeSet<char>> = transaction_list
.iter()
.map(|t| t.iter().map(|t| t).cloned().collect() )
.cloned().collect::<Vec<_>>();
}
错误消息是:
error: the trait `core::iter::FromIterator<char>` is not implemented for the type `&_` [E0277]
.map(|t| t.iter().map(|t| t).cloned().collect() )
^~~~~~~~~
help: see the detailed explanation for E0277
note: a collection of type `&_` cannot be built from an iterator over elements of type `char`
我没有找到从Vec<BTreeSet<char>>
中制作Vec<Vec<char>>
的正确方法。这是游乐场网址:http://is.gd/WVONHY。
答案 0 :(得分:4)
错误消息有点奇怪。这是解决方案:
let transaction_set: Vec<BTreeSet<_>> =
transaction_list
.iter()
.map(|t| t.iter().cloned().collect())
.collect();
两个主要变化是:
map(|x| x)
毫无意义。这是一个无操作。cloned
。 map
调用的结果类型已经是BTreeSet
。没有必要再次克隆它。后者修复了你的问题,让我们来看看定义:
fn cloned<'a, T>(self) -> Cloned<Self>
where Self: Iterator<Item=&'a T>,
T: 'a + Clone
为了能够调用cloned
,迭代器Item
必须是引用才能克隆。但是,您试图迭代BTreeSet
s,这不是引用。编译器选择告诉您,collect
char
的内部迭代器&_
无法进入cloned
(对某种类型的引用),这样就可以满足调用{{}的要求。 1}}。我的猜测是内部类型比collect
所需的类型具有更多的摆动空间。如果我们重写一下原始代码,在内部有一个更确定的类型:
let transaction_set: Vec<_> =
transaction_list
.iter()
.map(|t| -> BTreeSet<_> {t.iter().cloned().collect()})
.cloned().collect();
我们得到一组不同的错误:
error: type mismatch resolving `<[closure...] as core::ops::FnOnce<(&collections::vec::Vec<char>,)>>::Output == &_`:
expected struct `collections::btree::set::BTreeSet`,
found &-ptr [E0271]
.cloned().collect();
^~~~~~~~
error: no method named `collect` found for type `core::iter::Cloned<core::iter::Map<core::slice::Iter<'_, collections::vec::Vec<char>>, [closure...]>>` in the current scope
.cloned().collect();
^~~~~~~~~
note: the method `collect` exists but the following trait bounds were not satisfied: `core::iter::Cloned<core::iter::Map<core::slice::Iter<'_, collections::vec::Vec<char>>, [closure...]>> : core::iter::Iterator`
这有助于强调问题源于cloned
的外部使用。