将引用的 Vec 转换为值的 Vec 的惯用方法是什么? [英] What is the idiomatic way of converting a Vec of references to a Vec of values?

查看:96
本文介绍了将引用的 Vec 转换为值的 Vec 的惯用方法是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的函数返回一个 Vec 对元组的引用,但我需要一个 Vec 元组:

My function returns a Vec of references to a tuple, but I need a Vec of tuples:

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 循环进行转换,但我不喜欢它,我认为应该有一种模式惯用的方式:

I'm using a for loop to do the conversion, but I don't like it and I think there should be a mode idiomatic way:

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

推荐答案

从 1.36.0 更新

Rust 1.36.0 引入 已复制 的工作原理类似于 cloned,但使用了 Copy 特性,该特性要求副本便宜(例如 memcpy 仅).如果您有基本类型或实现 Copy 的类型,您可以改用它.

Update from 1.36.0

Rust 1.36.0 introduced copied which works like cloned, but uses the Copy trait, which has the requirement, that the copy is cheap (e.g. a memcpy only). If you have primitive types or types that implement Copy you can use that instead.

要使您的示例工作,请使用 克隆然后收集.

To make your example work, use cloned and then 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()
}

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

If your function accepts a slice, you have to use cloned twice.

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

这样做的原因是 iter() 返回切片引用的迭代器,结果为 &&T.

如果你碰巧有一个类型没有实现 Clone,您可以使用 map

If you happen to have a type that does not implement Clone, you can mimic the behavior with 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()
}

(游乐场)

这篇关于将引用的 Vec 转换为值的 Vec 的惯用方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆