从创建结构的宏的参数访问 self [英] Access to self from the parameters of a macro that creates a struct

查看:26
本文介绍了从创建结构的宏的参数访问 self的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试编写一个生成结构的宏.结构体的实现将由宏生成,但一些代码块将作为宏参数提供.这是此类宏的最小示例:

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 arguments. Here is a minimal example of such a macro:

macro_rules! make_struct {
    ($name:ident $block:block) => {
        struct $name {
            foo: i32,
        }

        impl $name {
            fn new() -> Self {
                $name { foo: 42 }
            }
            fn act (&self) {
                $block
            }
        }
    };
}

这里是如何使用宏的示例:

And here is an example of how the macro can be used:

fn main() {
    // Works
    make_struct!(Test { println! ("Bar: {:?}", 24); });
    let test = Test::new();
    test.act();
}

我想在所提供的代码中授予对 self 的访问权限.类似的东西:

I would like to give access to self inside the supplied code. Something like:

fn main() {
    // Does not work
    make_struct!(Test { println! ("Foo: {:?}", self.foo); });
    let test = Test::new();
    test.act();
}

我知道由于宏观卫生规则,这不起作用.具体来说,self.foo 表达式是在 main 函数的语法上下文中计算的,其中 self 不存在.问题是:有没有办法修改宏,以便可以从用户提供的代码中访问 self?

I understand that this does not work because of macro hygiene rules. Specifically, the self.foo expression is evaluated in the syntax context of the main function, where self does not exist. The question is: is there a way to modify the macro so that self may be accessed from the user-supplied code?

操场上的代码

推荐答案

通过向宏中添加一个参数来实现这一点,该参数存储了在块中访问 self 的名称:

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();
}

这篇关于从创建结构的宏的参数访问 self的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆