据我所知,Rust支持#[derive]
属性,以便在编译时从数据结构生成代码。如何为整个包,模块或函数生成代码?此处不允许使用#[derive]
属性。
我想生成一个涉及项目中多个项目(结构/枚举/函数)的函数。
例如,对于给定的示例模块
#[derive(MyAgg)]
mod AAA {
struct BBB {}
struct CCC {}
fn ddd() {}
}
我想制作这个。
fn example1() {
print("{:?}", AAA::BBB {});
print("{:?}", AAA::CCC {});
AAA::ddd()
}
这个例子没有意义,但我认为它提供了重点。
答案 0 :(得分:3)
模块上不允许#[derive]
属性,仅限于结构,枚举和联合:
error: `derive` may only be applied to structs, enums and unions
--> src/main.rs:1:1
|
1 | #[derive(MyAgg)]
| ^^^^^^^^^^^^^^^^
有关扩展#[derive]
宏的更多信息,请参阅Rust书中的Procedural Macros (and custom Derive)。
但是,您可以创建自己的过程宏。您可以咨询RFC以了解 proc-macros 。同样看看Serde或Derivative等其他包装箱也不会有什么坏处。
答案 1 :(得分:0)
我找到了解决方法。您可以生成Rust语言解析器并自己解析源代码。
首先,向Cargo.toml
添加依赖项。
[dependencies]
syntex_syntax = "0.59.1"
并将这些行添加到src/main.rs
。
extern crate syntex_syntax;
use std::path::*;
use syntex_syntax::parse::*;
use syntex_syntax::codemap::*;
fn main() {
let f = file!(); // Get absolute path to this file.
let p = Path::new(f);
let m = FilePathMapping::empty();
let s = ParseSess::new(m);
let r = parse_crate_from_file(&p, &s);
println!("{:?}", r);
}
现在你已经解析了AST。
更新
经过几周的尝试,我学会了在语法分析阶段完成宏扩展。当它在类型分析阶段之前执行时,我无法为每种类型查询完全解析的路径,因此从多个模块中稳定地引用多个类型变得非常困难或不可能。最后,我放弃了基于宏观的方法。