Is there a way to print a complete list of available type or instance members in Rust?
There is currently no built-in API so that you can get fields at runtime. However, you can get fields in two different ways.
- Declarative macros
macro_rules! generate_struct {
($name:ident {$($field_name:ident : $field_type:ty),+}) => {
struct $name { $($field_name: $field_type),+ }
impl $name {
fn introspect() {
$(
let field_name = stringify!($field_name);
let field_type = stringify!($field_type);
println!("Field Name: {:?} , Field Type: {:?}",field_name,field_type);
)*
}
}
};
}
generate_struct! { MyStruct { num: i32, s: String } }
fn main() {
MyStruct::introspect();
}
:
Field Name: "num" , Field Type: "i32"
Field Name: "s" , Field Type: "String"
, , (ref1, ref2, ref3).
custom derive "Instrospect". TokenStream syn crate.
#[proc_macro_derive(Introspect)]
pub fn derive_introspect(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as ItemStruct);
// ...
}
ItemStruct, ItemStruct fields(), .
, field name field type .
input
.fields
.iter()
.for_each(|field| match field.parse_named() {
Ok(field) => println!("{:?}", field),
Err(_) => println!("Field can not be parsed successfully"),
});
, :
let name = &input.ident;
let output = quote! {
impl #name {
pub fn introspect(){
input
.fields
.iter()
.for_each(|field| match field.parse_named() {
Ok(field) => println!("{:?}", field),
Err(_) => println!("Field can not be parsed successfully"),
});
}
}
};
// Return output TokenStream so your custom derive behavior will be attached.
TokenStream::from(output)
, :
#[derive(Introspect)]
struct MyStruct {
num: i32,
text: String
}
MyStruct::introspect();
. , , . Proc Macro Answer