如何解决使用`flat_map`在结构切片的字段上创建迭代器
给出结构的集合(向量/切片)。如何在每个结构的某些字段上创建组合的迭代器?
以下是使用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,这是一种不稳定的功能,它使得实现这种迭代器的方式更多方便。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。