使用JDK8开发应用的时候,经常会用到Lombok中的一些注解功能,比如使用@Data
来生成类成员的Get/Set 方法。
今天尝试下使用Rust中的过程宏来实现类似功能。
流程:
parse_macro_input
解析DeriveInput
format_ident!
拼接生成函数名称quote!
生成TokenStream段稍微复杂点就是quote子段,附加到主lombok_data_fun
的过程。
具体看例子:
// lib.rs
#[proc_macro_derive(Data)]
pub fn lombok_data(input: TokenStream)->TokenStream {
let input = parse_macro_input!(input as DeriveInput);
let data = input.data;
let mut lombok_data_fun= quote! { };
match data {
Data::Struct(s)=>{
// 遍历成员
for f in s.fields{
let attr_name = f.ident.to_token_stream();
let attr_ty = f.ty.to_token_stream();
// 拼接函数名称
let get_name = format_ident!("get_{}", attr_name.to_string());
let set_name = format_ident!("set_{}", attr_name.to_string());
let t = quote! {
pub fn #get_name(&self)->&#attr_ty{
&self.#attr_name
}
pub fn #set_name(&mut self, val:#attr_ty){
self.#attr_name = val
}
};
// 由子段拼接成主段
lombok_data_fun = quote! {
#lombok_data_fun
#t
}
}
},
_=>()
}
// 获取结构名称
let name = input.ident.to_token_stream();
let expanded = quote! {
impl #name {
#lombok_data_fun
}
};
expanded.into()
}
// main.rs
#[derive(Data)]
struct LombokTest {
name: String,
age : i32,
}
fn main() {
let mut test = LombokTest {
name: "Baby".to_string(),
age: 10,
};
test.set_name("张三".to_string());
println!("{}", test.get_name());
}
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。