我的函数返回一个元组引用的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);
}

最佳答案

从1.36.0更新
Rust 1.36.0引入了 copied ,其功能类似于cloned,但使用了Copy特性,该特性要求副本便宜(例如仅memcpy)。如果您具有原始类型或实现Copy的类型,则可以改用它。

为了使您的示例正常工作,请使用 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 `clone_vec`, but with another syntax
    vec.into_iter().map(Foo::dup).collect()
}
(playground)

09-25 18:42