如何在宏中调用自身的方法?
Posted
技术标签:
【中文标题】如何在宏中调用自身的方法?【英文标题】:How to call methods on self in macros? 【发布时间】:2017-10-22 13:25:28 【问题描述】:macro_rules! call_on_self
($F:ident) =>
self.$F()
struct F;
impl F
fn dummy(&self)
fn test(&self)
call_on_self!(dummy);
以上不起作用(Playground):
error[E0424]: expected value, found module `self`
--> src/lib.rs:3:9
|
3 | self.$F()
| ^^^^ `self` value is a keyword only available in methods with `self` parameter
...
11 | call_on_self!(dummy);
| --------------------- in this macro invocation
我不明白为什么这不起作用:宏是在 self
可用的方法中调用的!这有可能吗?我是否应该将self
传递给宏,否则宏无法解析self
?
我正在使用 rustc 1.19.0-nightly。
【问题讨论】:
如果gen_match
仅被test
使用,您可以将macro_rules!
移动到函数内部。
【参考方案1】:
Rust 宏不仅仅是文本替换。相反,有几个重要的区别,其中之一是“宏观卫生”。有了这个,宏内部的标识符不会干扰外部的标识符,这确实可以防止像 C 那样的宏系统经常发生的几个错误。
因此,宏只能访问以下标识符:
明确通过,或 在定义宏时在范围内。虽然乍一看似乎是不必要的限制,但它实际上有助于提高代码的可读性。否则,这是“远处的幽灵行动”。在 Rust 中通过 some_fn(&mut foo)
将变量的引用传递给函数的原因或多或少是相同的,并且不像在 C++ 中那样隐式(some_fn(foo)
):更清楚的是函数在调用时如何使用变量网站。
这意味着我们有两种方法可以解决您的问题。标准解决方案是将self
传递给宏:
macro_rules! call_on_self
($self:ident, $F:ident) =>
$self.$F()
;
struct F;
impl F
fn dummy(&self)
fn test(&self)
call_on_self!(self, dummy);
如果您只需要在test
方法内使用宏,您可以在该方法内定义宏。然后,self
在定义宏时已经在作用域内,因此它可以在不传递self
的情况下工作:
struct F;
impl F
fn dummy(&self)
fn test(&self)
macro_rules! call_on_self
($F:ident) =>
self.$F()
;
call_on_self!(dummy);
这两者还有一些有趣的组合,比如定义一个显式接受self
的宏,以及在函数内部定义另一个宏来捕获self
:
macro_rules! call_on_self_outer
($self:ident, $F:ident) =>
$self.$F()
;
struct F;
impl F
fn dummy(&self)
fn test(&self)
macro_rules! call_on_self
($F:ident) =>
call_on_self_outer!(self, $F);
;
call_on_self!(dummy);
`
【讨论】:
以上是关于如何在宏中调用自身的方法?的主要内容,如果未能解决你的问题,请参考以下文章
如何在宏中获取Scala-macro-annotated类或对象的扩展类路径?
MS Visual Studio 2010 C++ 预处理器 - 如果函数在宏中定义并在其他地方调用,未定义时是不是有任何开销