我的函数返回一个对元组的引用Vec
,但是我需要一个Vec
个元组:
use std::collections::HashSet;
fn main() {
let maxs: HashSet<(usize, usize)> = HashSet::new();
let mins: HashSet<(usize, usize)> = HashSet::new();
let intersection = maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>();
}
我应该如何进行转换?
错误:
19 | maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>()
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected tuple, found reference
|
= note: expected type `std::vec::Vec<(usize, usize)>`
found type `std::vec::Vec<&(usize, usize)>`
我是using a for
loop to do the conversion,但我不喜欢它,我认为应该有一种惯用的方式:
for t in maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>().iter() {
output.push(**t);
}
答案 0 :(得分:8)
要使示例生效,请先使用cloned
,然后再使用collect
。
let maxs: HashSet<(usize,usize)> = HashSet::new();
let mins: HashSet<(usize,usize)> = HashSet::new();
let output: Vec<(usize, usize)> = maxs.intersection(&mins).cloned().collect();
除了实现Clone
之外,此解决方案还可以用于任何类型:
pub fn clone_vec<T: Clone>(vec: Vec<&T>) -> Vec<T> {
vec.into_iter().cloned().collect()
}
如果函数接受切片,则必须使用cloned
两次。
pub fn clone_slice<T: Clone>(slice: &[&T]) -> Vec<T> {
slice.iter().cloned().cloned().collect()
}
这样做的原因是iter()
在切片的引用上返回了一个迭代器,结果是&&T
。
如果您碰巧具有无法实现Clone
的类型,则可以使用map
来模仿行为
pub struct Foo(u32);
impl Foo {
fn dup(&self) -> Self {
Foo(self.0)
}
}
pub fn clone_vec(vec: Vec<&Foo>) -> Vec<Foo> {
vec.into_iter().map(|f| f.dup()).collect()
}
pub fn clone_vec2(vec: Vec<&Foo>) -> Vec<Foo> {
// this function is identical to `ret_tup`, but with another syntax
vec.into_iter().map(Foo::dup).collect()
}