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

Rust macro_rules如何在重复模式中过滤带const标记的结构体字段

原代码失效原因

macro_rules! 不存在「内层宏优先求值」的特性,你在宏参数位置嵌套的decl_struct!(@gen_struct_member ...)调用会被直接当作普通标记传递,不会提前展开为字段名,因此后续的结构体生成分支无法正常匹配。


可行实现方案

采用增量累积递归的思路处理字段过滤,逐字段判断是否保留,把符合要求的字段累积到列表中,全部处理完成后再一次性生成结构体,具体实现如下:

macro_rules! decl_struct {
    // 入口分支:匹配宏调用结构,初始化空的字段累积列表
    {
        $name:ident {
            $( $kind:ident $member:ident, )*
        }
    } => {
        decl_struct!(@process_fields $name [] $( $kind $member, )*);
    };

    // 递归终止分支:所有字段处理完毕,用累积的合法字段生成结构体
    {
        @process_fields $name:ident [ $( $member:ident, )* ]
    } => {
        struct $name {
            $( $member: u32 /* 可根据需求替换为自定义类型 */, )*
        }
    };

    // 递归处理分支1:当前字段是mut,加入累积列表,继续处理剩余字段
    {
        @process_fields $name:ident [ $( $acc:ident, )* ]
        mut $member:ident, $( $rest_kind:ident $rest_member:ident, )*
    } => {
        decl_struct!(@process_fields $name [ $( $acc, )* $member, ] $( $rest_kind $rest_member, )*);
    };

    // 递归处理分支2:当前字段是const,跳过该字段,继续处理剩余字段
    {
        @process_fields $name:ident [ $( $acc:ident, )* ]
        const $member:ident, $( $rest_kind:ident $rest_member:ident, )*
    } => {
        decl_struct!(@process_fields $name [ $( $acc, )* ] $( $rest_kind $rest_member, )*);
    };
}

// 测试调用
decl_struct! {
    MyStruct {
        mut foo,
        const bar,
    }
}

// 验证:生成的MyStruct仅包含foo字段
fn main() {
    let s = MyStruct { foo: 123 };
    println!("{}", s.foo);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 01:36:01