【问题标题】:Repetition inside an optional pattern可选模式内的重复
【发布时间】:2021-10-01 13:46:41
【问题描述】:

我正在尝试根据可选模式$( … )? 的存在来选择生成一个结构:

macro_rules! accounts_struct {
    (
        $( #[seeds: struct $StructSeedsName:ident] )?
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
        
        $(
            pub struct $StructSeedsName {
                $(
                    pub $account: u8,
                )*
            }
        )?
    }
}

accounts_struct! {
    #[seeds: struct Seeds]
    struct Accounts {
        pub foo,
        pub bar,
    }
}

Playground.

很遗憾,我似乎不被允许这样做:

error: meta-variable `StructSeedsName` repeats 1 time, but `account` repeats 2 times
  --> src/lib.rs:16:10
   |
16 |           $(
   |  __________^
17 | |             pub struct $StructSeedsName {
18 | |                 $(
19 | |                     pub $account: u8,
20 | |                 )*
21 | |             }
22 | |         )?
   | |_________^

我可以使用什么解决方法?

【问题讨论】:

  • 这个问题是我的一个问题,但答案并不符合我的问题:stackoverflow.com/questions/61045284/…
  • 如果我理解了这个问题,我必须将重复嵌套在扩展部分中,就像在声明部分中一样。

标签: rust macros


【解决方案1】:

作为最后的手段,您可以像这样重复自己,以涵盖可选部分存在和不存在的情况

macro_rules! accounts_struct {
    (
        #[seeds: struct $StructSeedsName:ident]
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
        
        
        pub struct $StructSeedsName {
            $(
                pub $account: String,
            )*    
        }
    };
    (
        struct $StructAccountsName:ident {
            $(
                pub $account:ident,
            )*
        }
    ) => {
        pub struct $StructAccountsName {
            $(
                pub $account: String,
            )*
        }
    };
}

【讨论】:

  • 是的,我想这就是我要做的。在我的实际用例中,生成了数百行代码,因此我无法重复所有代码,但我可以添加一个带有内部表示的中间步骤:play.rust-lang.org/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-09-15
  • 2019-12-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多