Access to self from the parameters of a macro that creates a struct

前端 未结 2 986
无人及你
无人及你 2021-01-22 05:54

I\'m trying to write a macro that generates a struct. The implementation for the struct will be generated by the macro, but some blocks of code will be provided as macro argumen

相关标签:
2条回答
  • 2021-01-22 06:25

    You can pass a closure instead of a block.

    make_struct!(Test |this| println!("Foo: {:?}", this.foo));
    

    Then the macro can use the closure and call it with self:

    macro_rules! make_struct {
        ($name:ident $closure:expr) => {
            struct $name {
                foo: i32,
            }
    
            impl $name {
                fn new() -> Self {
                    $name { foo: 42 }
                }
                fn act (&self) {
                    let x: &Fn(&Self) = &$closure;
                    x(self)
                }
            }
        };
    }
    

    The dance with the let binding is necessary, because the type of this in the closure can't be inferred (yet?). And it also makes your macro's error reporting a little more readable when something other than a closure is passed.

    0 讨论(0)
  • 2021-01-22 06:34

    Found a way to do it by adding a parameter to the macro that stores the name by which self will be accessed in the blocks:

    macro_rules! make_struct {
        ($myname:ident : $type_name:ident $block:block) => {
            struct $type_name {
                foo: i32,
            }
    
            impl $type_name {
                fn new() -> Self {
                    $type_name { foo: 42 }
                }
                fn act (&self) {
                    let $myname = self;
                    $block
                }
            }
        };
    }
    
    fn main() {
        make_struct!(myself: Test { println! ("Foo: {:?}", myself.foo); });
        let test = Test::new();
        test.act();
    }
    
    0 讨论(0)
提交回复
热议问题