2016-11-03 2 views
0

Wenn wir die Anwendung von #[derive(...)] auf eine Struktur verallgemeinern wollen, wäre es in einigen Fällen nützlich, dies in ein Makro zu schreiben.Ist es möglich, eine Strukturdeklaration in einem Makro zu verschachteln, um Strukturattribute anzuwenden?

Nicht-Arbeits Beispiel:

my_traits!(
    pub struct MyType(u32), 
    MyType 
); 

Wo my_traits das erste Argument mit #[derive(...)] Präfix könnte, und verwenden Sie das zweite Argument impl SomeTrait for $t {...} zu erklären.

Deklaration Implementierungen funktioniert ohne Probleme, jedoch habe ich es nicht geschafft, einen Weg zu finden, ein Makro zu verwenden, um die Struktur Deklaration mit Attributen Präfix.


diese Frage finden Sie ein Beispiel dessen, was dies für verwendet werden könnte:
Possible to derive attributes *after* a struct declaration?

Antwort

2

Putting #[derive(...)] in das Makro scheint gut zu funktionieren:

#[derive(Eq,PartialEq,Debug)] 
struct Foo(u32); 

macro_rules! my_eq(
    ($name:ident) => { 
     #[derive(Eq,PartialEq,Debug)] 
     struct $name(u32); 
    }; 
); 

my_eq!(Bar); 

fn main() { 
    assert_eq!(Foo(3), Foo(3)); 
    assert!(Foo(3) != Foo(4)); 
    assert_eq!(Bar(3), Bar(3)); 
    assert!(Bar(3) != Bar(4)); 

} 

Playground link

Or Wenn Sie die ganze struct in:

übergeben möchten
macro_rules! my_eq(
    ($name:item) => { 
     #[derive(Eq,PartialEq,Debug)] 
     $name 
    }; 
); 

my_eq!(struct Bar(u32);); 

Playground

Beachten Sie, dass das Makro ein ganzes Stück nimmt, so das Semikolon innerhalb des Makroaufruf benötigt wird (Foo{} structs brauchen es nicht, wie wenn inline geschrieben).

+0

Danke, ich könnte am Ende dies tun. Die Hauptnachteile dazu - während das funktioniert, wollte ich die gesamte Deklaration übergeben, sonst Ill müssen separate Makros für 'pub struct $ name (u32);' und 'struct $ name (pub u32);' (öffentliche Struktur und öffentliches Mitglied). – ideasman42

0

Dies kann getan werden, indem Sie eine item, Antwort dank @j_ey auf IRC.

macro_rules! ideas { 
    ($ty: item, $id: ident) => { 
     #[derive(Debug)] 
     $ty 
     impl $id { 
      fn doit(){} 
     } 
    } 
} 

ideas!(pub struct Foo(u32);, Foo); 

fn main() { 
    let f = Foo(1); 
    println!("{:?}", f); 
} 
Verwandte Themen