宏可以生成其他数据吗?

时间:2016-06-26 18:33:22

标签: macros rust

foo!(x, y, z);
// expands to
fn xx(self) -> T {..}
fn xy(self) -> T {..}
...
fn xxx(self) -> T {..}
fn xxy(self) -> T {..}
fn xyz(self) -> T {..}
fn xzx(self) -> T {..}
//and so on
...

宏可以生成其他数据吗?我想实现矢量调配。 Vector4有很多种组合。 4 + 2 ^ 2 + 3 ^ 3 + 4 ^ 4 = 291种组合

除了简单的替换之外我还没有用宏做任何事情,所以我想知道是否可以表达这样的东西或者我是否需要编译器插件呢?

1 个答案:

答案 0 :(得分:1)

Rust支持3种代码生成方法:

  • 使用macro!
  • 声明的宏
  • 依赖插件的程序宏(不稳定)
  • build.rs

后者是一个内置的build script,专门支持代码生成/第三方库构建(例如C库)。

在您的情况下,您在Code Generation部分特别感兴趣,这很简单(引用文档):

// build.rs

use std::env;
use std::fs::File;
use std::io::Write;
use std::path::Path;

fn main() {
    let out_dir = env::var("OUT_DIR").unwrap();
    let dest_path = Path::new(&out_dir).join("hello.rs");
    let mut f = File::create(&dest_path).unwrap();

    f.write_all(b"
        pub fn message() -> &'static str {
            \"Hello, World!\"
        }
    ").unwrap();
}

鉴于此,您可以在构建开始之前自动生成任何.rs文件,而不会遇到宏卫生问题或不得不依赖于夜间编译器。