我希望能够得到以下内容:
macro_rules! impl_a_method(
($obj:ident, $body:block) => (
fn a_method(foo: Foo, bar: Bar, baz: Baz) -> $obj $body
)
)
// Implementation would look like:
impl_a_method!(MyType, {
MyType {
foo: foo.blah(),
bar: bar.bloo(),
baz: baz.floozy(),
}
})
我的真实世界示例包含具有更大签名的方法,我必须以30种不同类型的独特方式实现这些方法。
我尝试过类似于上面的宏,但是我遇到了错误,其中rustc在扩展站点考虑了foo
,bar
和baz
未解析的名称(尽管我&#39 ;确定宏声明在词法上先于使用)。
是否可以做这样的事情?
如果没有,你能推荐一种能达到类似效果的方法吗?
答案 0 :(得分:6)
由于宏观卫生,这是不可能的。宏体中引入的任何标识符都保证与宏调用站点上的任何标识符不同。您必须自己提供所有标识符,这有点违背了宏的目的:
impl_a_method!(MyType, (foo, bar, baz), {
MyType {
foo: foo.blah(),
bar: bar.bloo(),
baz: baz.floozy(),
}
})
这是由这个宏完成的:
macro_rules! impl_a_method(
($obj:ty, ($_foo:ident, $_bar:ident, $_baz:ident), $body:expr) => (
fn a_method($_foo: Foo, $_bar: Bar, $_baz: Baz) -> $obj { $body }
)
)
你唯一能真正保存的就是编写方法参数类型。