如何在 Rust 中传递单个结构实例和交互器以映射

How to pass a single struct instance along with an interator to map in Rust

提问人:skrhee 提问时间:11/17/2023 最后编辑:cafce25skrhee 更新时间:11/17/2023 访问量:52

问:

我想遍历一个,但也要把一个结构实例传递给我的函数。Vec<T>

这个想法是,我可以在每个进程中单独创建结构实例的副本,并根据存储在 .Vec<T>

同样,我有一组初始条件存储在 Vec 中,我想迭代使用这些条件来修改一组结构实例副本。.iter()

我幼稚的猜测是,我必须创建一个长度相同的附加副本,然后在我的结构实例中创建许多副本,但我想知道是否有更有效的方法,每个进程都可以创建副本。Vec<StructType>Vec<T>Vec<StructType>,

这是我尝试执行的操作的概述,尽管我不确定将其传递给我的函数的最佳方式是什么。struct_instance

// --- PreProcessing ---
let struct_instance <StructType> = read_inputs(json);

// --- Iteration ---
let initial_conditions: Vec<i32> = (1..5).collect();
let test: Vec<i32> = initial_conditions
    .iter()
    .map(calculation_function)
    .collect();

我从代码片段中省略了 and 的定义,因为我觉得完整的定义可能会偏离问题的要点。read_inputscalculation_function

我后来想用人造丝并行完成这项任务,这就是我选择使用这种方法的原因。.iter()

loops rust vector struct rayon

评论

1赞 Jared Smith 11/17/2023
你想要。。。在 VEC 中,您可以迭代修改的一堆结构副本,可能并行修改?为什么不在迭代器的每一轮中克隆原始结构呢?这与这些有什么关系?结构是否应该是您想要部分应用的额外参数?我很欣赏你试图削减这一点,但你已经剥离得足够多了,以至于我真的不明白你在这里要求什么。calculate_function
4赞 cafce25 11/17/2023
虽然可能不需要完整的定义,但它的签名肯定是。caculation_function
0赞 skrhee 11/17/2023
@cafce25,感谢您的编辑,这个问题现在肯定得到了改进,更具可读性。
1赞 skrhee 11/17/2023
@JaredSmith,谢谢你的问题,是的,你的理解是正确的。我认为解决这个问题有两种可能性。第一种可能性是我创建了两个向量,一个由重复了很多次的结构实例组成的向量,以及一个具有修改结构实例所需的初始条件的向量。第二种可能性是我在迭代器的每一轮中克隆原始结构,但我不确定如何执行第二种方法。
0赞 skrhee 11/17/2023
@cafce25,我同意函数签名是绝对需要的。 初始条件是初始条件的一个索引。struct_instance是结构体的一个实例,它是单个结构体实例的索引还是单个结构体实例的索引取决于我们采用哪种路径来解决问题。下面的@Sam回答显示了解决问题的第一种方法,我不确定如何进行第二种方法。calculation_function(initial_condition, struct_instance)Vec<T>Vec<StructType>

答:

2赞 Sam 11/17/2023 #1

iter::repeat(SomeStruct { .. })将为您提供一个重复初始结构定义的迭代器。

initial_condition.iter().zip(iter::repeat(SomeStruct { .. })将为您提供一个迭代器,该迭代器为 initial_condition 集合中包含的每个值提供一个元组。(initial_condition, some_struct)

一个完整的示例如下。我将测试类型从 更改为 ,因为您似乎想要收集初始结构的修改版本,但我可能误解了您的要求。i32SomeStruct

use std::iter;

#[derive(Clone, Debug)]
struct SomeStruct {
    value: i32,
}

fn main() {
    let structs = iter::repeat(SomeStruct { value: 0 });

    let initial_conditions: Vec<i32> = (1..5).collect();
    let test: Vec<SomeStruct> = initial_conditions
        .iter()
        .zip(structs)
        .map(|(initial_condition, mut somestruct)| {
            somestruct.value = *initial_condition;
            somestruct
        })
        .collect();

}

评论

0赞 skrhee 11/17/2023
谢谢@Sam这正是我想要的!