在 Rust 中要实现“发现类并生成动态注册代码”做法与 Go 的ast包思路不同。Go 是在运行时解析源码而 Rust 则利用其强大的编译时代码生成能力来实现。这里有两种主流方式可以分别满足“灵活发现”和“自动注册”的需求。️ 方式一自己解析源码类似 Go AST 的思路如果希望在编译前扫描源文件、提取类型信息并生成代码可以组合使用下面几个库构建一套自己的代码生成工具链解析源文件 (syn): 这是 Rust 生态中最流行的解析库用于将 Rust 源码解析成抽象语法树AST。你可以在build.rs脚本中使用它读取并分析指定目录下的所有.rs文件找出所有符合条件例如带有特定注解的结构体或枚举。从结构体提取信息 (quote): 配合syn使用quote库能帮你把提取到的信息拼接成新的 Rust 代码。这是生成注册代码的核心工具。在编译时自动运行: 将上述逻辑放在项目的build.rs文件中。这样每次执行cargo build时你的代码生成逻辑就会先运行然后生成的代码会被编译进最终的程序里。社区中有不少项目都采用了这个思路例如dust使用类似方式读取 Dart 注解并生成代码rust-ontogen也使用build.rs解析并生成完整的服务端代码。bevy_reflect的派生宏 (#[derive(Reflect)]) 在编译时进行的反射信息生成也与此类似。 方式二用“注册器”实现自动注册更符合 Rust 习惯另一种方法不是去“发现”类型而是依赖开发者通过属性宏Attribute Macro在定义类型时就声明“我要注册”宏会自动生成注册代码。这种方式更接近“在编译时收集注册信息”的思路。核心机制使用类似#[inventory]来自interoptopus等库的模式。当你为结构体或函数标注#[ffi]或#[service]这样的宏时这个宏会为你的类型生成一个“注册器”实现。如何使用你不需要手动去扫描源码只需要在定义类型的地方加上宏然后在统一入口比如一个inventory()函数中通过register!(MyType)这样的宏调用将所有带有标记的类型“收集”起来。bevy_reflect的TypeRegistry也提供了类似的运行时注册方式允许你通过register::MyStruct()来手动注册类型。 如何选择如果你需要处理未标记的、或第三方 crate 中的类型那么方式一使用synbuild.rs自己解析是唯一的选择因为只有扫描源码才能“发现”这些未知类型。如果你只想为自己的代码中的类型生成注册逻辑那么方式二使用属性宏是更简单、更符合 Rust 习惯的做法。它利用宏系统在编译时“知道”你的类型并自动为其生成注册代码省去了手动解析的麻烦。 方案对比速览对比维度自行解析源码 (build.rs syn)使用属性宏 (如 interoptopus/inventory)核心库syn,quote项目提供的属性宏 (如#[ffi])工作原理在build.rs中扫描、解析源码文件生成 Rust 代码文件。宏在编译时处理类型定义生成对应的注册代码。能否发现第三方类型✅ 是可以解析外部 crate 的源码。❌ 否只能处理被自身宏标记的类型。使用复杂度较高需要处理文件 I/O 和 AST 解析。较低只需为类型添加注解并在入口处汇总调用。典型应用dust,rust-ontogeninteroptopus你是打算为项目中的自定义类型生成注册代码还是需要处理外部 crate 中的类型如果方便说下具体场景我可以帮你看看更贴合的例子。