You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Rust中能否不借助额外数组遍历枚举(enum)元素?

在Rust中无需额外数组枚举Enum所有变体的方法

Rust的枚举本身没有内置的“遍历所有变体”机制,因为变体本质是构造函数而非可直接枚举的数值。但可以通过以下方式实现类似效果,无需显式声明全局数组:

方法1:为Enum实现迭代器方法

手动为Expr实现一个关联函数,把所有变体实例的数组封装到方法内部,外部调用时看不到显式数组:

enum Expr {
    Null,
    Add(i32, i32),
    Sub(i32, i32),
    Mul(i32, i32),
    Div { dividend: i32, divisor: i32 },
    Val(i32),
}

impl Expr {
    // 返回包含所有变体实例的迭代器
    fn iter() -> impl Iterator<Item = Expr> {
        [
            Expr::Null,
            Expr::Add(3, 4),
            Expr::Sub(10, 5),
            Expr::Mul(6, 2),
            Expr::Div { dividend: 15, divisor: 3 },
            Expr::Val(42),
        ].into_iter()
    }
}

fn main() {
    for expr in Expr::iter() {
        match expr {
            Expr::Null => println!("Null expression"),
            Expr::Add(a, b) => println!("Addition: {} + {}", a, b),
            Expr::Sub(a, b) => println!("Subtraction: {} - {}", a, b),
            Expr::Mul(a, b) => println!("Multiplication: {} * {}", a, b),
            Expr::Div { dividend, divisor } => println!("Division: {} / {}", dividend, divisor),
            Expr::Val(value) => println!("Value: {}", value),
        }
    }
}

方法2:用宏生成变体实例列表

如果变体数量较多,手动编写实例麻烦,可以用宏把数组定义隐藏起来:

enum Expr {
    Null,
    Add(i32, i32),
    Sub(i32, i32),
    Mul(i32, i32),
    Div { dividend: i32, divisor: i32 },
    Val(i32),
}

macro_rules! expr_variants {
    () => {
        [
            Expr::Null,
            Expr::Add(3, 4),
            Expr::Sub(10, 5),
            Expr::Mul(6, 2),
            Expr::Div { dividend: 15, divisor: 3 },
            Expr::Val(42),
        ]
    };
}

fn main() {
    for expr in expr_variants!().iter() {
        match expr {
            Expr::Null => println!("Null expression"),
            Expr::Add(a, b) => println!("Addition: {} + {}", a, b),
            Expr::Sub(a, b) => println!("Subtraction: {} - {}", a, b),
            Expr::Mul(a, b) => println!("Multiplication: {} * {}", a, b),
            Expr::Div { dividend, divisor } => println!("Division: {} / {}", dividend, divisor),
            Expr::Val(value) => println!("Value: {}", value),
        }
    }
}

关键说明

  • 必须为每个变体提供具体实例值:枚举变体本身是构造器(比如Expr::Add是函数),只有传入参数生成实例后,才能作为可遍历的Expr类型值。
  • 新增变体需同步更新:后续如果给Expr加新变体,要手动更新iter()方法或宏的内容,否则新变体不会被遍历到。

内容的提问来源于stack exchange,提问作者user366312

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 23:25:29