Я пишу процедурный макрос, и мне нужно многократно выдавать очень длинный идентификатор (например, из-за гигиены ). Я использую quote!
для создания TokenStream
с, но я не хочу повторять длинный идентификатор снова и снова!
Например, я хочу сгенерировать этот код:
let very_long_ident_is_very_long_indeed = 3;
println!("{}", very_long_ident_is_very_long_indeed);
println!("twice: {}", very_long_ident_is_very_long_indeed + very_long_ident_is_very_long_indeed);
Я знаю, что могу создать Ident
и интерполировать его в quote!
:
let my_ident = Ident::new("very_long_ident_is_very_long_indeed", Span::call_site());
quote! {
let #my_ident = 3;
println!("{}", #my_ident);
println!("twice: {}", #my_ident + #my_ident);
}
Пока все хорошо, но мне нужно использовать этот идентификатор во многих функциях по всей моей кодовой базе , Я хочу, чтобы это был const
, который я могу использовать везде. Однако это не удается:
const FOO: Ident = Ident::new("very_long_ident_is_very_long_indeed", Span::call_site());
С этой ошибкой:
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src/lib.rs:5:70
|
5 | const FOO: Ident = Ident::new("very_long_ident_is_very_long_indeed", Span::call_site());
| ^^^^^^^^^^^^^^^^^
error[E0015]: calls in constants are limited to constant functions, tuple structs and tuple variants
--> src/lib.rs:5:20
|
5 | const FOO: Ident = Ident::new("very_long_ident_is_very_long_indeed", Span::call_site());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Я сомневаюсь, что эти функции будут отмечены const
в ближайшее время.
Я мог бы сделать саму строку константой:
const IDENT: &str = "very_long_ident_is_very_long_indeed";
Но тогда, где бы я ни хотел использовать идентификатор, мне нужно вызывать Ident::new(IDENT, Span::call_site())
, что было бы довольно раздражающе. Я хочу просто написать #IDENT
в моем quote!
вызове. Можно ли как-нибудь заставить это работать?