【问题标题】:Can a macro generate additional data?宏可以生成额外的数据吗?
【发布时间】:2016-10-28 18:02:11
【问题描述】:
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 种组合

除了简单的替换,我没有对宏做任何事情,所以我想知道是否可以表达类似的东西,或者我需要编译器插件吗?

【问题讨论】:

  • “附加数据”是一个非常通用的概念。你真的是在问一个宏是否可以根据宏输入生成任意数量的函数?
  • @Shepmaster 是的,我基本上想生成宏输入的排列。
  • 那么答案是basically no。 (或this)。 (或this)。
  • 如果您同意这是重复的,请随意将其标记为最有用的。如果你不这样做,edit 你的问题来解释差异。
  • @Shepmaster:我注意到没有一个重复提到使用构建脚本(在 Rust 中,由于集成到构建系统中,它比其他语言更方便)。它可能是一个合理的替代方案……取决于问题的具体情况。

标签: macros rust


【解决方案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 文件,而不会遇到宏卫生问题或不得不依赖夜间编译器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-11-26
    • 1970-01-01
    • 2020-02-05
    • 1970-01-01
    • 1970-01-01
    • 2018-07-13
    • 2010-11-12
    相关资源
    最近更新 更多