这个宏应该能够通过参数替换字符串中的条目。例如,这样做是可行的:
let string = "Hello, world!";
replace_macro!(string, "world", "Rust"); // Hello, Rust!我不知道如何做到这一点,因为我以前所有的尝试都只是编写一个常规函数并调用宏中不起作用的函数。如果可能的话,我希望使用macro_rules而不是proc宏。
发布于 2022-04-09 22:25:56
这是不可能的。宏无法检查和/或更改变量的值。
如果文字嵌入到调用(replace_macro!("Hello, world!", "world", "Rust");)中,但需要一个proc-宏:macro_rules!宏无法检查和/或更改文本,则有可能。
这是一个非常简单的proc宏:
use quote::ToTokens;
use syn::parse::Parser;
use syn::spanned::Spanned;
type Args = syn::punctuated::Punctuated<syn::LitStr, syn::Token![,]>;
#[proc_macro]
pub fn replace_macro(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
let input_span = input.span();
let args = match Args::parse_terminated.parse(input) {
Ok(args) => Vec::from_iter(args),
Err(err) => return err.into_compile_error().into(),
};
let (original, text, replacement) = match args.as_slice() {
[original, text, replacement] => (original.value(), text.value(), replacement.value()),
_ => {
return syn::Error::new(
input_span,
r#"expected `"<original>", "<text>", "<replacement>"`"#,
)
.into_compile_error()
.into()
}
};
original
.replace(&text, &replacement)
.into_token_stream()
.into()
}它解析由逗号点缀的三个字符串文字的列表,然后调用str::replace()来完成真正的工作。
https://stackoverflow.com/questions/71812185
复制相似问题