2016-05-10 21 views
6

Esiste qualche equivalente di Object.keys() di JS per Rust's struct?Come ottenere nomi di campi struct in Rust?

Ho bisogno di qualcosa per generare intestazioni CSV (io uso rust-csv) dai nomi dei campi della struttura.

struct Export { 
    first_name: String, 
    last_name: String, 
    gender: String, 
    date_of_birth: String, 
    address: String 
} 

//... some code 

let mut wrtr = Writer::from_file("/home/me/export.csv").unwrap().delimiter(b'\t'); 

wrtr.encode(/* WHAT TO WRITE HERE TO GET STRUCT NAMES as tuple of strings or somethings */).is_ok() 
+0

Non è possibile farlo senza un plugin * rustc * (funziona solo di notte). – mcarton

+0

Grazie a @mcarton. Leggerò di [Compiler Plugins] (https://doc.rust-lang.org/book/compiler-plugins.html). Mi piace davvero mantenere certi dati in un posto, quindi usare il nome del campo potrebbe essere ottimo. E potrei passare alla notte, quindi ogni aiuto è apprezzato. –

+3

Improbabile che abbia bisogno di un plug-in per il compilatore per il vostro attuale utilizzo; può probabilmente usare '# [derive (RustcDecodable)]' come [descritto nel repository] (https://github.com/BurntSushi/rust-csv). Tuttavia, non risponde alla domanda che stai ponendo, che è un modo generico di elencare ** qualsiasi ** nome di campo delle strutture. Il mio vecchio amico, il [XY Problem] (http://xyproblem.info/). – Shepmaster

risposta

7

La corrente principale metodo di metaprogrammazione in ruggine è via macros. In questo caso, è possibile catturare tutti i nomi dei campi e quindi aggiungere un metodo che restituisce forme stringa di loro:

macro_rules! zoom_and_enhance { 
    (struct $name:ident { $($fname:ident : $ftype:ty),* }) => { 
     struct $name { 
      $($fname : $ftype),* 
     } 

     impl $name { 
      fn field_names() -> &'static [&'static str] { 
       static NAMES: &'static [&'static str] = &[$(stringify!($fname)),*]; 
       NAMES 
      } 
     } 
    } 
} 

zoom_and_enhance!{ 
struct Export { 
    first_name: String, 
    last_name: String, 
    gender: String, 
    date_of_birth: String, 
    address: String 
} 
} 

fn main() { 
    println!("{:?}", Export::field_names()); 
} 

Per le macro avanzate, essere sicuri di controllare The Little Book of Rust Macros.

+1

domanda simile e soluzione: http://stackoverflow.com/a/29986760/996886 – melak47

+1

@ melak47 buon punto! Pensi che questa domanda debba essere contrassegnata come duplicata? – Shepmaster

+0

puoi migliorarla ..? aspetta, migliorerò esso. – jayphelps