【问题标题】:What's wrong with this Rust macro?这个 Rust 宏有什么问题?
【发布时间】:2017-12-02 09:00:02
【问题描述】:

我正在尝试编写一个宏,通过将类型包装在某个变体中来为枚举生成 From impl。

我想出了这个:

macro_rules! variant_derive_from {
    ($enum:ty:$variant:ident($from:ty)) => {
        impl From<$from> for $enum {
            fn from(thing: $from) -> $enum { return $enum::$variant(thing) }
        }
    };
}

但是,每当我尝试实际使用此宏时,我都会收到以下错误:

error: expected expression, found `B`
|             fn from(thing: $from) -> $enum { $enum::$variant(thing) }
|                                               ^^^^

我无法弄清楚为什么会发生这种情况,所以我运行了一个带有宏跟踪的构建,并且该宏显然扩展为以下(当然是虚拟类型):

impl From < A > for B { fn from ( thing : A ) -> B { B :: AVariant ( thing ) } }

将其直接粘贴到代码中时,它会成功编译。什么给了??

Here's a full example of the error.

【问题讨论】:

    标签: macros rust


    【解决方案1】:

    ty 占位符只能用作类型,不能用作命名空间。在您的示例中使用 ident 应该可以正常工作。

    ident 不接受 paths ("foo::Bar") (并且在这种情况下使用 path 似乎也不起作用);您应该能够通过手动构建路径来解决它,例如匹配这个:$enum:ident $(:: $enum_path:ident)*(像这样使用它:$enum $(:: $enum_path)*)。

    【讨论】:

    • 如果枚举是通用的或者不是当前文件直接used,这不会导致问题吗?
    • 你是对的;我也想过,只是编辑了我的答案:)
    • 啊,我想可以类似地构造泛型支持。
    • 嗯...泛型可以但生命周期不能。无论如何,这似乎是一个非常极端的情况,所以我会忽略它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多