Methods 是否可以编写一个将扩展为函数/方法签名的Rust宏?

Methods 是否可以编写一个将扩展为函数/方法签名的Rust宏?,methods,macros,rust,method-signature,Methods,Macros,Rust,Method Signature,我希望能够做到以下几点: 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

我希望能够做到以下几点:

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
未解析名称时,我遇到了错误(尽管我确信宏声明在词汇上先于使用)

有可能这样做吗


如果没有,你能推荐一种可以实现类似效果的方法吗?

由于宏观卫生的原因,这是不可能的。宏主体中引入的任何标识符都保证与宏调用站点中的任何标识符不同。您必须自己提供所有标识符,这在某种程度上违背了宏的目的:

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

这里真正保存的是编写方法参数的类型。

“宏卫生”实际上是一个非常明确的概念:在Julia中有一个函数
esc
,它使引入的符号保持原样,而不是转换为唯一的名称(gensymed)。Rust中没有这样的东西吗?@PostSelf我认为没有-获得未替换标识符的唯一方法是将其外部传递。我相信这是故意的。我想知道这是否至少在proc宏中是可能的?我试过写一个,但似乎不起作用,但我不知道这是否只是因为我做错了什么。卫生不应成为prog宏的障碍,因为它们通常不卫生。