如何在属性过程宏的文档字符串中使用quote!将类型插值为字符串
如何在属性过程宏的文档字符串中使用quote!将类型插值为字符串
我完全懂你遇到的问题——你想让宏生成的文档注释里自动替换成实际的枚举表示类型(比如把repr(#typ)变成repr(u8)),但现在quote!里的文档字符串直接把#typ当成了普通文本,根本没做插值替换。
问题出在:quote!的插值语法只作用于它能识别的Rust语法节点,而字符串内部的#typ只是普通字符,不会被quote!处理。所以得换个方式,把文档注释拆成可以插值的片段,让#typ作为实际的插值项嵌入进去。
下面是修改后的代码,重点看标注的变化部分:
首先,我们需要先把传入的类型typ转换成它的字符串表示,这样才能插入到文档注释里:
// 在解析完args和input之后,添加这行代码 let typ_str = quote!(#typ).to_string();
然后修改生成方法的quote!部分,把原来的多行文档注释换成多个#[doc]属性拼接的方式,这样就能把typ_str插值进去:
let body = match input.data { Data::Enum(_) => { quote! { #[doc = "Returns the discriminant value of the enum."] #[doc = ""] #[doc = "# Safety"] #[doc = ""] #[doc = "This method is safe, because the macro guarantees that the enum is repr("] #[doc = #typ_str] #[doc = ")."] pub const fn #method_name(&self) -> #typ { #[allow(unsafe_code)] unsafe { *::core::ptr::from_ref(self) .cast::<#typ>() } } } } _ => unimplemented!(), };
为什么这样能行?
Rust允许用多个#[doc = "..."]属性拼接成一段完整的文档注释。我们把原来的文档字符串拆成几个部分,把类型的字符串表示typ_str作为单独的#[doc]项插入进去,这样quote!就会正确把它替换成实际的类型(比如u8)。
用你提供的例子测试的话,生成的代码里的文档注释就会变成:
/// Returns the discriminant value of the enum. /// /// # Safety /// /// This method is safe, because the macro guarantees that the enum is repr(u8).
完全符合你的需求!这样修改之后,宏生成的文档就会准确显示枚举的实际表示类型了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

