将引用向量转换为值向量的惯用方法是什么



我的函数返回对元组的引用的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)>`

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

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()
}

(操场(

最新更新