syn::Idents 的逗号分隔列表

Comma separated list of syn::Idents

我想加一些syn::Ident组成一个&'static str。所有 Ident 应该连接起来形成逗号分隔和字符串化(因为这就是我如何获得 Ident 的字符串表示形式)&'static str.

我这里有一个不工作的项目:https://github.com/Jasperav/comma_separated(在 example 文件夹中有一个失败的测试)。

这是我的测试:

#[test]
fn test_another_struct() {
    assert_eq!("name, another_name", AnotherStruct::useless())
}

失败是因为:

Expected :nameanother_name Actual :name, another_name

这是我试图生成逗号分隔列表的代码(在 lib.rs 内):

let idents = vec![
    syn::Ident::new("name", Span::call_site()),
    syn::Ident::new("another_name", Span::call_site())
];

proc_macro::TokenStream::from(quote! {
    impl #struct_name {
        fn useless() -> &'static str {
            concat!(#(stringify!(#idents)),*)
        }
    }
})

我不明白为什么它不起作用。我的宏中有 1 ,,这意味着:用逗号分隔所有内容吧?

如果你 cargo expand 你的代码,你会发现你扩展成这样:

(假设 struct_nameFoo

impl Foo {
    fn useless() -> &'static str {
        concat!(stringify!(name), stringify!(another_name))
    }
}

stringify!直接将ident转换成字符串, 所以返回值相当于

concat!("name", "another_name")

这里,逗号是语法的分隔符,不是字符串文字, 所以你最终得到 nameanother_name.

仅考虑上面的代码,最方便的解决方法是在 proc_macro 代码中制定原始字符串 而不是依赖 stringify!concat!, 允许您使用像 slice::join.

这样的 API