Rust:有没有办法在宏类型参数上调用静态函数?

Mic*_*ell 3 macros rust

这段代码:

#![feature(macro_rules)]

macro_rules! new(
    ($my_type:ty) => ( $my_type::new() );
)

struct Foo {
    blah: int
}

impl Foo {
    fn new() -> Foo {
        return Foo { blah: 0 }
    }
}

fn main() {
    let my_foo = new!(Foo);
    println!("Foo's value: {}", my_foo.blah);
}
Run Code Online (Sandbox Code Playgroud)

看起来不错,但它失败并出现此错误:

test.rs:4:25: 4:32 error: unexpected token: `Foo`
test.rs:4     ($my_type:ty) => ( $my_type::new() );
                                  ^~~~~~~
Run Code Online (Sandbox Code Playgroud)

如果我进入宏并$my_typeFoo它替换编译并运行得很好,那么Foo在那个位置显然是有效的.除非Foo来自宏观替代,显然.

如果我运行rustc test.rs --pretty expanded,它不会显示扩展的宏.它只是给了我相同的错误信息.我怀疑这意味着它在扩展宏之前生成了消息,但它可能只是因为除非编译成功,否则它不会显示任何内容.虽然这会严重限制其有用性--pretty expanded.

基于其他实验,我可以在基本上每个其他地方使用宏类型参数,期望一个类型工作.你不能在它们上面调用静态函数.这似乎是一个相当随意的限制,错误信息肯定没有用.

为什么存在这种限制?它有办法吗?

huo*_*uon 6

Foo::bar()语法创建路径Foo::bar,然后调用该函数,只有具有有效路径的作品,它不与任意类型的工作,如(u8, i8)::bar()不能正常工作.您可以使用ident宏非终端,它采用单个标识符,并且可以在标识符有效的情况下使用,包括在路径内

#![feature(macro_rules)]

macro_rules! new(
    ($my_type: ident) => ( $my_type::new() );
)

struct Foo {
    blah: int
}

impl Foo {
    fn new() -> Foo {
        return Foo { blah: 0 }
    }
}

fn main() {
    let my_foo = new!(Foo);
    println!("Foo's value: {}", my_foo.blah);
}
Run Code Online (Sandbox Code Playgroud)

UFCS提供了通过语法在任意类型上调用此类方法<Type>::new(),因此,在实现时,用.替换当前的宏

macro_rules! new(
    ($my_type: ty) => ( <$my_type>::new() );
)
Run Code Online (Sandbox Code Playgroud)

也应该工作.