【发布时间】:2020-12-13 05:24:24
【问题描述】:
我有一个具有不同变体可能性的枚举,如下所示:
pub enum Enum {
Empty,
Single(Struct),
Multi(Vec<Struct>),
}
我想创建典型的三个迭代函数来获取 Enum 的 Structs:一个 .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);
}
}
}
我没有看到如何将 iter::empty 和 iter::once 强制转换为 slice::Iter 和 vec::IntoIter,或者这是否是正确的做法?
【问题讨论】:
-
出于好奇,你为什么有这个枚举?为什么不直接使用
Vec? -
我在这里简化了我的实际用例。实际上,这些代表不同的操作。一个操作(认为 NOT)只需要一个输入,但另一个操作(认为 OR)需要多个输入,而另一个是不接受任何输入的虚拟操作。所以真的
Enum { Terminal, Not(Struct), Or(Vec<Struct>) }