Rust宏:根据参数数量重复n次,而无需使用实际参数。

7

是否有可能根据参数的数量重复执行某个操作n次,而无需使用实际参数?我的用例是实现一个枚举 变量,它接受1个或多个类型参数以及使用通配符匹配枚举变量的实现。因此,通配符的数量将取决于提供的参数数量。 例如:

macro_rules! impl_enum {
    ($name: ident, $($params: ty)+, $val:expr) => {
        enum MyEnum {
            $name($($params)+,)
        }
        impl MyEnum {
            fn get_val(self) {
                match self {
                    MyEnum::$name(??????) => $val
                }
            }
        }
    }
}

现在我想要输出的是:
impl_enum!(Variant1, Type1 Type2 Type3, 42);

成为

            enum MyEnum {
                Variant1(Type1, Type2, Type3),
            }
            impl MyEnum {
                fn get_val(self) {
                    match self {
                        MyEnum::Variant1(_,_,_) => 42,
                    }
                }
            }

可以的吗?
2个回答

5
你可以使用将ty转换为下划线的宏来完成此操作:
macro_rules! type_as_underscore {
    ( $t: ty ) => { _ };
}

现在,使用这个修复你的宏中的一些其他错误:

macro_rules! impl_enum {
    ($name: ident, $($params: ty)+, $val:expr) => {
        enum MyEnum {
            $name($($params),+)
        }
        impl MyEnum {
            fn get_val(self) {
                match self {
                    MyEnum::$name($(type_as_underscore!($params)),+) => $val
                };
            }
        }
    };
}

1
在夜间版本中,这是由实验性功能 macro_metavar_expr 支持的。您可以在重复表达式中添加 ${ignore(metavariable)} 来标记您希望它基于 metavariable,但实际上不会发出它:
#![feature(macro_metavar_expr)]

macro_rules! impl_enum {
    ($name: ident, $($params: ty)+, $val:expr) => {
        enum MyEnum {
            $name($($params),+)
        }
        impl MyEnum {
            fn get_val(self) {
                match self {
                    MyEnum::$name($( ${ignore(params)} _ ),*) => $val
                }
            }
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接