Rust 如何实现iterable变量枚举的InIterator?
我有一个枚举,它有不同的变体,例如:Rust 如何实现iterable变量枚举的InIterator?,rust,enums,iterator,Rust,Enums,Iterator,我有一个枚举,它有不同的变体,例如: 发布枚举枚举{ 空的,, 单个(结构), 多(Vec), } 我想创建典型的三个迭代函数来获取Enum的Structs:一个.iter()函数用于引用迭代器,两个.into_iter()函数用于获取引用和值的迭代器。如何做到这一点 以下是我失败的尝试: use std::{iter, slice, vec}; #[derive(Debug)] pub struct Struct(u32); #[derive(Debug)] pub enum Enum
发布枚举枚举{
空的,,
单个(结构),
多(Vec),
}
我想创建典型的三个迭代函数来获取Enum
的Struct
s:一个.iter()
函数用于引用迭代器,两个.into_iter()
函数用于获取引用和值的迭代器。如何做到这一点
以下是我失败的尝试:
use std::{iter, slice, vec};
#[derive(Debug)]
pub struct Struct(u32);
#[derive(Debug)]
pub enum Enum {
Empty,
Single(Struct),
Multi(Vec<Struct>),
}
impl Enum {
fn iter(&self) -> slice::Iter<'_, Struct> {
match self {
Enum::Empty => iter::empty(),
Enum::Single(s) => iter::once(s),
Enum::Multi(v) => v.iter(),
}
}
}
impl IntoIterator for Enum {
type Item = Struct;
type IntoIter = vec::IntoIter<Struct>;
fn into_iter(self) -> Self::IntoIter {
match self {
Enum::Empty => iter::empty(),
Enum::Single(s) => iter::once(s),
Enum::Multi(v) => v.into_iter(),
}
}
}
impl<'a> IntoIterator for &'a Enum {
type Item = &'a Struct;
type IntoIter = slice::Iter<'a, Struct>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn main() {
let enums = vec![
Enum::Empty,
Enum::Single(Struct(1)),
Enum::Multi(vec![Struct(2), Struct(3)])];
for e in enums {
for s in e.iter() {
println!(".iter() over refs: {:?}", s);
}
for s in &e { // leverages IntoIterator for &'a Enum
println!(".into_iter() over refs: {:?}", s);
}
for s in e { // leverages IntoIterator for Enum
println!(".into_iter() moves: {:?}", s);
}
}
}
使用std:{iter,slice,vec};
#[导出(调试)]
发布结构(u32);
#[导出(调试)]
发布枚举{
空的,,
单个(结构),
多(Vec),
}
impl枚举{
fn iter(&self)->slice::iter intointerator for&'a Enum{
类型项=&'a结构;
输入IntoIter=slice::Iter在本例中,所有这些变体都可以用切片表示,或者很容易地转换为Vec
s。因此,您可以这样做,然后直接使用它们的迭代器
impl IntoIterator for Enum {
type Item = Struct;
type IntoIter = vec::IntoIter<Struct>;
fn into_iter(self) -> vec::IntoIter<Struct> {
let vec = match self {
Enum::Empty => Vec::new(),
Enum::Single(single) => vec![single],
Enum::Multi(vec) => vec,
};
vec.into_iter()
}
}
impl<'a> IntoIterator for &'a Enum {
type Item = &'a Struct;
type IntoIter = slice::Iter<'a, Struct>;
fn into_iter(self) -> slice::Iter<'a, Struct> {
let slice = match self {
Enum::Empty => &[],
Enum::Single(single) => std::slice::from_ref(single),
Enum::Multi(vec) => vec.as_slice(),
};
slice.iter()
}
}
枚举的impl into迭代器{
类型项=结构;
输入IntoIter=vec::IntoIter;
fn输入iter(self)->vec::输入iter{
让vec=匹配self{
Enum::Empty=>Vec::new(),
Enum::Single(Single)=>vec![Single],
枚举::多(vec)=>vec,
};
vec.into_iter()
}
}
impl;
fn到iter(self)->切片::iter{
空(标准:国际热核实验堆:空),
用于枚举的Multi(std::slice::Iter迭代器选项为&'a Enum的迭代器{
类型项=&'a结构;
输入IntoIter=EnumIter{
匹配自我{
Enum::Empty=>EnumIter::Empty(std::iter::Empty()),
Enum::Single(Single)=>EnumIter::Single(std::iter::once(Single)),
Enum::Multi(vec)=>EnumIter::Multi(vec.iter()),
}
}
}
出于好奇,请在上查看它,为什么有这个枚举?为什么不使用普通的
Vec
?我在这里简化了我的实际用例。实际上,这些代表不同的操作。一个操作(不思考)只需要一个输入,但另一个操作(思考或)接受多个,另一个是不接受任何操作的伪操作这是最有效的方法吗?为了得到一个兼容的迭代器,必须创建一个空的Vec,这感觉很奇怪——但这可能和其他方法一样有效吗?为空的情况创建一个Vec不是问题,单一的情况是最糟糕的,因为它实际上必须进行分配才能得到一个兼容的迭代器旧的单一元素。我添加了一个更接近原始代码的示例实现。我不能确定哪一个更好,尽管转换为vecs更简洁。
pub enum EnumIntoIter {
Empty(std::iter::Empty<Struct>),
Single(std::iter::Once<Struct>),
Multi(std::vec::IntoIter<Struct>),
}
impl Iterator for EnumIntoIter {
type Item = Struct;
fn next(&mut self) -> Option<Struct> {
match self {
EnumIntoIter::Empty(iter) => iter.next(),
EnumIntoIter::Single(iter) => iter.next(),
EnumIntoIter::Multi(iter) => iter.next(),
}
}
}
impl IntoIterator for Enum {
type Item = Struct;
type IntoIter = EnumIntoIter;
fn into_iter(self) -> EnumIntoIter {
match self {
Enum::Empty => EnumIntoIter::Empty(std::iter::empty()),
Enum::Single(single) => EnumIntoIter::Single(std::iter::once(single)),
Enum::Multi(vec) => EnumIntoIter::Multi(vec.into_iter()),
}
}
}
pub enum EnumIter<'a> {
Empty(std::iter::Empty<&'a Struct>),
Single(std::iter::Once<&'a Struct>),
Multi(std::slice::Iter<'a, Struct>),
}
impl<'a> Iterator for EnumIter<'a> {
type Item = &'a Struct;
fn next(&mut self) -> Option<&'a Struct> {
match self {
EnumIter::Empty(iter) => iter.next(),
EnumIter::Single(iter) => iter.next(),
EnumIter::Multi(iter) => iter.next(),
}
}
}
impl<'a> IntoIterator for &'a Enum {
type Item = &'a Struct;
type IntoIter = EnumIter<'a>;
fn into_iter(self) -> EnumIter<'a> {
match self {
Enum::Empty => EnumIter::Empty(std::iter::empty()),
Enum::Single(single) => EnumIter::Single(std::iter::once(single)),
Enum::Multi(vec) => EnumIter::Multi(vec.iter()),
}
}
}