gpt4 book ai didi

rust - 使用 `flat_map`在字段上为结构片创建迭代器

转载 作者:行者123 更新时间:2023-12-03 11:33:54 26 4
gpt4 key购买 nike

给定结构的集合(向量/切片)。如何在每个结构的某些字段上创建组合的迭代器?
以下是使用flat_map的具体尝试:

struct Game {
home_team: u8,
away_team: u8,
}

fn teams(games: &[Game]) -> impl Iterator<Item = u8> {
games
.iter()
.flat_map(|game| [game.home_team, game.away_team].iter().map(|x| x.clone()))
}
fn main() {
let data = &[
Game {
home_team: 1,
away_team: 2,
},
Game {
home_team: 1,
away_team: 3,
},
];
let non_unique_teams: Vec<u8> = teams(data).collect();
}
我的实际用例非常相似。特别是,构成迭代器基础的字段实现了 Copy,从而使克隆过程非常完美。
我的直觉告诉我,这应该行得通,因为我正在克隆我需要从传入切片中“取出”的唯一内容。显然,我对借阅检查器的理解很差,我无法掌握这一点。

最佳答案

迭代器需要拥有包含struct字段副本的内存。在您的代码中,创建一个本地数组并在其上调用iter(),这将导致对不拥有数据的切片引用进行迭代。
使迭代器拥有数据的最简单方法是为每个结构分配一个向量:

fn teams(games: &[Game]) -> impl Iterator<Item = u8> + '_ {
games
.iter()
.flat_map(|game| vec![game.home_team, game.away_team])
}
这将导致在每次迭代中分配堆。性能损失可能是最小的,因为分配器可能能够在每次迭代中重用分配。但是,如果出于某种原因要避免分配,则也可以结合使用 Iterator::chain()std::iter::once():
use std::iter::once;

fn teams(games: &[Game]) -> impl Iterator<Item = u8> + '_ {
games
.iter()
.flat_map(|game| once(game.home_team).chain(once(game.away_team)))
}
进一步的替代方法包括 implementing IntoIterator and Clone for Game ,它使您可以简单地使用 games.iter().cloned().flatten() iter_vals crate或使用 generators(一种不稳定的功能,使实现这种迭代器更加方便)。

关于rust - 使用 `flat_map`在字段上为结构片创建迭代器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64007000/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com