使用reify和eval可以很容易地在Scala中编写健康的宏。但是it's not always possible需要使用reify和eval。
那么,如果不能使用它们,那么有什么规则可以确保宏是健康的呢?有没有办法测试一个宏,以确保不会有不良的卫生状况从裂缝中溜走?
upd。在后来的里程碑2.10.0中,Expr.eval被重命名为Expr.splice。
发布于 2012-04-24 11:19:10
Reify是卫生的,因为它将符号与标识和这棵树一起保存。
如果你的宏扩展结果没有符号附加到标识项上(例如,你只需要标识(“x”)来指定一个名为x的引用),那么随后的宏扩展类型检查将把x绑定到调用点作用域中的任何东西(或者如果该作用域没有x,你将得到一个编译错误)。
相反,当你的宏展开中有标识符号时,类型检查器不会尝试重新解析它们,而只是简单地使用它已有的符号。这意味着,当您具体化一个表达式并在宏扩展中使用结果时,它将把它的符号带到调用点。当然,不是所有的符号,例如,不可能引用局部变量或私有/受保护的东西,但对全局可访问声明的引用是持久的。
底线是检查你的宏是否是卫生的,检查你的is和that是否有附加的符号。您可以通过实例化或手动将符号分配给手工制作的树来实现这一点。
发布于 2012-04-24 02:23:59
因为reify是一个宏,所以我只看它的实现来弄清楚它是做什么的。
https://stackoverflow.com/questions/10277758
复制相似问题