Struct 有没有办法将递归结构/枚举装箱为默认值?

Struct 有没有办法将递归结构/枚举装箱为默认值?,struct,enums,rust,box,Struct,Enums,Rust,Box,如果我试图在Rust中定义递归结构/枚举: enum Enum { A, B(Enum), C(Enum, i32), D(Enum, Enum), ... } 正如预期的那样,我将得到一个编译错误 我知道解决这个问题的一个可能的方法是用如下方框包装所有递归引用: enum Enum { A, B(Box<Enum>), C(Box<Enum>, i32), D(Box<Enum>, B

如果我试图在Rust中定义递归结构/枚举:

enum Enum {
    A,
    B(Enum),
    C(Enum, i32),
    D(Enum, Enum),
    ...
}
正如预期的那样,我将得到一个编译错误

我知道解决这个问题的一个可能的方法是用如下方框包装所有递归引用:

enum Enum {
    A,
    B(Box<Enum>),
    C(Box<Enum>, i32),
    D(Box<Enum>, Box<Enum>),
    ...
}
这让我想知道是否有可能以某种方式自动完成它?有这样的宏吗

#[boxed]
enum Enum {
    A,
    B(Enum),
    C(Enum, i32),
    D(Enum, Enum),
    ...
}

我强烈建议使用显式写出整个枚举的经典方法

但是,关于你的可能性问题,我认为在一定程度上可以做到:

macro_rules! boxed_enum{
    ($dummy: ident, enum $E: ident $($variant:tt)* ) => {
        pub mod $dummy {
            type $E = Box<$dummy>;
            pub enum $dummy $($variant)*
        }
        type $E = $dummy::$dummy;
    }
}

boxed_enum!(InnerEnum, enum Enum {
    A,
    B(Enum),
    C(Enum, i32),
    D(Enum, Enum),
});
宏采用$dummy,这是技巧中所述的辅助模块和辅助枚举的名称,并键入别名将虚拟枚举别名为所需标识符

我认为可以从$E生成$dummy,这样用户就不需要显式地指定它。然而,这将取决于混凝土标识iirc(仅限夜间)或其他板条箱,如浆糊


如前所述,在这种情况下,我将采用手动解决方案。

由于无法在常规宏中检查令牌的相等性,因此必须在过程宏中执行此操作,这将有很多工作要做,这项功能的好处是什么?虽然您可以制作一个过程宏,用Box替换所有Enum,但要正确地完成这项工作还是很困难的。例如,您不想以Vec结束,所以您需要在这个特殊情况下以及其他许多情况下进行测试。考虑到你几乎不需要对递归类型进行装箱,这样的宏几乎没有什么好处。我不喜欢这个问题,因为它要求混淆代码以获得微小的美学收益,但我对这个答案的独创性印象深刻。干得好,先生!
macro_rules! boxed_enum{
    ($dummy: ident, enum $E: ident $($variant:tt)* ) => {
        pub mod $dummy {
            type $E = Box<$dummy>;
            pub enum $dummy $($variant)*
        }
        type $E = $dummy::$dummy;
    }
}

boxed_enum!(InnerEnum, enum Enum {
    A,
    B(Enum),
    C(Enum, i32),
    D(Enum, Enum),
});