将引用的Vec转换为值的Vec的惯用方法是什么?

Igo*_*bin 7 iterator reference rust

我的函数返回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)>>();
}
Run Code Online (Sandbox Code Playgroud)

我该如何进行转换?

错误:

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)>`
Run Code Online (Sandbox Code Playgroud)

我正在使用for循环来进行转换,但我不喜欢它,我认为应该有一种模式惯用的方式:

for t in maxs.intersection(&mins).collect::<Vec<&(usize, usize)>>().iter() {
    output.push(**t);
}
Run Code Online (Sandbox Code Playgroud)

hel*_*low 11

要使您的示例正常工作,请使用copied然后cloned.

let maxs: HashSet<(usize,usize)> = HashSet::new();
let mins: HashSet<(usize,usize)> = HashSet::new();
let output: Vec<(usize, usize)> = maxs.intersection(&mins).cloned().collect();
Run Code Online (Sandbox Code Playgroud)

此解决方案适用于除实现之外的任何类型Copy:

pub fn clone_vec<T: Clone>(vec: Vec<&T>) -> Vec<T> {
    vec.into_iter().cloned().collect()
}
Run Code Online (Sandbox Code Playgroud)

如果您的函数接受切片,则必须使用memcpy两次.

pub fn clone_slice<T: Clone>(slice: &[&T]) -> Vec<T> {
    slice.iter().cloned().cloned().collect()
}
Run Code Online (Sandbox Code Playgroud)

这样做的原因是Copy返回一个迭代器而不是切片的引用,这导致了cloned.


如果您碰巧有一个未实现的类型collect,您可以模仿该行为Clone

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()
}
Run Code Online (Sandbox Code Playgroud)

(游乐场)

  • *你不能使用`into_iter`* - 你可以,并且该函数拥有切片,它只是有同样的问题. (2认同)