首页 > 解决方案 > 如何在 serde crate 中合并宏和特征?

问题描述

当我使用 serde 的 Serialize 宏时,我将 Macro 和 Trait 一起使用,因此我不需要额外导入 trait。

#[serde::Serialize)]
struct Abc {
  a: 4
}

它是如何工作的?当我尝试实现此功能时,我找不到可行的解决方案,也无法在互联网上找到有关此的内容。

这是一个片段,我在 serde 逻辑中找到了这个功能

pub mod traits;

pub use traits::Example;

#[cfg(feature = "lib_derive")]
#[macro_use]
extern crate lib_derive;
#[cfg(feature = "lib_derive")]
pub use lib_derive::Example;

在这种情况下,编译器会在 note: 中抛出错误this error originates in the derive macro 'lib::Example',因此它没有找到 Trait,但在 serde crate 中它可以工作。

我在这里错过了什么?

标签: rustrust-macros

解决方案


我现在理解问题和编译器的注释。

您必须在 crate 中的宏中添加类型的路径,然后它会像预期的那样工作得很好,如果您忘记了这一点,您必须添加use lib::Example;, 来指定您的特征,因为它在范围内是未知的。

有了这个例子,它就可以工作了。

#[proc_macro_derive(Example)]
pub fn example_derive(input: TokenStream) -> TokenStream {
  let ast = syn::parse(input).unwrap();
    impl_example_macro(&ast)
}

fn impl_example_macro(ast: &syn::DeriveInput) -> TokenStream {
  let name = &ast.ident;
  let gen = quote! {
        impl lib::Example for #name {
            fn example(&self) {}
        }
    };
  gen.into()
}

推荐阅读