Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/rust/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Rust 如何避免迭代器::平面映射中的分配?_Rust_Iterator_Declarative - Fatal编程技术网

Rust 如何避免迭代器::平面映射中的分配?

Rust 如何避免迭代器::平面映射中的分配?,rust,iterator,declarative,Rust,Iterator,Declarative,我有一个整数的向量,我想创建一个新的向量,它包含这些整数和这些整数的平方。我可以强制这样做: 让v=vec![1, 2, 3]; 让mut new_v=Vec::new;//为了简单起见,新的而不是带有_容量。 用于v.iter中的&x{ 新(v.pushx),; 新_v.pushx*x; } 普林顿!{:?},新的_v; 但是我想使用迭代器。我想出了这个密码: 让v=vec![1, 2, 3]; 让new_v:Vec=v.iter .flat|u map|和x|vec![x,x*x] 收集 普

我有一个整数的向量,我想创建一个新的向量,它包含这些整数和这些整数的平方。我可以强制这样做:

让v=vec![1, 2, 3]; 让mut new_v=Vec::new;//为了简单起见,新的而不是带有_容量。 用于v.iter中的&x{ 新(v.pushx),; 新_v.pushx*x; } 普林顿!{:?},新的_v; 但是我想使用迭代器。我想出了这个密码:

让v=vec![1, 2, 3]; 让new_v:Vec=v.iter .flat|u map|和x|vec![x,x*x] 收集 普林顿!{:?},新的_v; 但它在flat_map函数中分配了一个中间Vec

如何在没有分配的情况下使用平面地图?

您可以使用一个

let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
    .flat_map(|&x| ArrayVec::from([x, x * x]))
    .collect();
通过值迭代器生成数组,这样您就不需要ArrayVec了,请参阅和链接的PRs。

您可以使用

let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
    .flat_map(|&x| ArrayVec::from([x, x * x]))
    .collect();

将数组设置为按值迭代器,这样您就不需要ArrayVec了,请参阅和链接的PRs。

如果您的迭代器很小,并且不需要任何外部依赖项,则可以使用和构造一个短迭代器。比如说,

use std::iter;

let v = vec![1, 2, 3];
let new_v: Vec<_> = v
    .iter()
    .flat_map(|&x| iter::once(x).chain(iter::once(x * x)))
    .collect();
println!("{:?}", new_v);
这可以做成一个宏,不过要注意,对太多的元素使用它可能会导致达到递归限制。如果要为几十个以上的元素创建迭代器,那么进行分配可能还不错。如果您确实需要略微提高性能,nnnmmm的解决方案可能会更好

macro_rules! small_iter {
    () => { std::iter::empty() };
    ($x: expr) => {
        std::iter::once($x)
    };
    ($x: expr, $($y: tt)*) => {
        std::iter::once($x).chain(small_iter!($($y)*))
    };
}

fn main() {
    let v = vec![1, 2, 3];
    let new_v: Vec<_> = v
        .iter()
        .flat_map(|&x| small_iter!(x, x * x))
        .collect();
    println!("{:?}", new_v);
}

如果您的迭代器很小,并且不需要任何外部依赖项,那么可以从和构造一个短迭代器。比如说,

use std::iter;

let v = vec![1, 2, 3];
let new_v: Vec<_> = v
    .iter()
    .flat_map(|&x| iter::once(x).chain(iter::once(x * x)))
    .collect();
println!("{:?}", new_v);
这可以做成一个宏,不过要注意,对太多的元素使用它可能会导致达到递归限制。如果要为几十个以上的元素创建迭代器,那么进行分配可能还不错。如果您确实需要略微提高性能,nnnmmm的解决方案可能会更好

macro_rules! small_iter {
    () => { std::iter::empty() };
    ($x: expr) => {
        std::iter::once($x)
    };
    ($x: expr, $($y: tt)*) => {
        std::iter::once($x).chain(small_iter!($($y)*))
    };
}

fn main() {
    let v = vec![1, 2, 3];
    let new_v: Vec<_> = v
        .iter()
        .flat_map(|&x| small_iter!(x, x * x))
        .collect();
    println!("{:?}", new_v);
}

从1.51.0版开始,struct core::array::IntoIter已经稳定。您可以这样使用它:

use core::array;

let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
    .flat_map(|&x| array::IntoIter::new([x, x * x]))
    .collect();

文档警告说,将来在为数组实现InIterator时,这可能会被弃用,但目前这是最简单的方法。

从1.51.0版开始,struct core::array::InIter已经稳定。您可以这样使用它:

use core::array;

let v = vec![1, 2, 3];
let new_v: Vec<_> = v.iter()
    .flat_map(|&x| array::IntoIter::new([x, x * x]))
    .collect();

文档警告说,将来在为数组实现IntoIterator时,可能会不推荐使用此方法,但目前这是最简单的方法。

要清楚,可能不推荐使用的方法是使用新函数创建,而不是array::IntoIter本身。如果数组真的进入迭代器,您就可以只编写平面映射|&x |[x,x*x]。更清楚的是,可能不推荐使用的是使用新函数创建,而不是array::IntoIter本身。如果数组真的进入迭代器,您就可以只编写平面映射|&x |[x,x*x]。