如何在Rust中实现类C/C++宏展开以消除冗余代码(编译时处理)
将C++编译期宏生成常量的逻辑转换为Rust实现
需求说明
现有一段C++代码,通过宏展开生成全局常量对象,希望转换为Rust实现,要求:
- 所有处理在编译期完成,避免运行时开销
- 无需显式声明每个常量对象,通过宏批量生成
- 代码结构清晰,能直观看到展开后的对象属性
原C++代码
#include <iostream> #include <string> struct ObjAttribution { std::string id; struct attribute { std::string file_name; int code; std::string companion_name; attribute(std::string f, int c, std::string cn) : file_name(f), code(c), companion_name(cn) {} } attribute_type; ObjAttribution(std::string i, std::string f, int c, std::string cn) : id(i) , attribute_type(f, c, cn) {} }; #define CONST_ATTRIBUTE(id, x, y, z) const ObjAttribution id(#id, #x, y, #z); #define _x_(id, x, y, z) CONST_ATTRIBUTE(id, x, y, z) // 生成全局常量对象 _x_(USER_IO, user_info.txt, 64, user_companion.txt) _x_(USER_IO_1, user_info_1.txt, 65, user_companion_1.txt) _x_(USER_IO_2, user_info_2.txt, 66, user_companion_2.txt) _x_(USER_IO_3, user_info_3.txt, 67, user_companion_3.txt) _x_(USER_IO_4, user_info_4.txt, 68, user_companion_4.txt) _x_(USER_IO_5, user_info_5.txt, 69, user_companion_5.txt) _x_(USER_IO_6, user_info_6.txt, 70, user_companion_6.txt) _x_(USER_IO_7, user_info_7.txt, 71, user_companion_7.txt) _x_(USER_IO_8, user_info_8.txt, 72, user_companion_8.txt) int main() { std::cout << USER_IO_1.id << " --> " << USER_IO_1.attribute_type.file_name << " --> " << USER_IO_1.attribute_type.code << " --> " << USER_IO_1.attribute_type.companion_name << "\n"; std::cout << USER_IO_2.id << " --> " << USER_IO_2.attribute_type.file_name << " --> " << USER_IO_2.attribute_type.code << " --> " << USER_IO_2.attribute_type.companion_name << "\n"; std::cout << USER_IO_3.id << " --> " << USER_IO_3.attribute_type.file_name << " --> " << USER_IO_3.attribute_type.code << " --> " << USER_IO_3.attribute_type.companion_name << "\n"; std::cout << USER_IO_4.id << " --> " << USER_IO_4.attribute_type.file_name << " --> " << USER_IO_4.attribute_type.code << " --> " << USER_IO_4.attribute_type.companion_name << "\n"; std::cout << USER_IO_5.id << " --> " << USER_IO_5.attribute_type.file_name << " --> " << USER_IO_5.attribute_type.code << " --> " << USER_IO_5.attribute_type.companion_name << "\n"; std::cout << USER_IO_6.id << " --> " << USER_IO_6.attribute_type.file_name << " --> " << USER_IO_6.attribute_type.code << " --> " << USER_IO_6.attribute_type.companion_name << "\n"; std::cout << USER_IO_7.id << " --> " << USER_IO_7.attribute_type.file_name << " --> " << USER_IO_7.attribute_type.code << " --> " << USER_IO_7.attribute_type.companion_name << "\n"; return 0; }
Rust实现方案
Rust中可以通过声明宏实现编译期生成全局常量,同时用&'static str保证字符串在编译期就被嵌入二进制,完全符合编译期处理的要求。
完整代码
// 定义编译期可构造的结构体,所有字段都是静态生命周期的字符串或整数 #[derive(Debug)] struct Attribute { file_name: &'static str, code: i32, companion_name: &'static str, } #[derive(Debug)] struct ObjAttribution { id: &'static str, attribute_type: Attribute, } // 声明宏:生成全局常量对象,参数对应C++宏的输入 #[macro_export] macro_rules! const_attribute { ($id:ident, $file_name:literal, $code:expr, $companion_name:literal) => { // 生成全局常量,const保证编译期初始化 pub const $id: ObjAttribution = ObjAttribution { id: stringify!($id), // 将标识符转为字符串,对应C++的#id attribute_type: Attribute { file_name: $file_name, code: $code, companion_name: $companion_name, }, }; }; } // 简化宏调用,和原C++的_x_宏对应 #[macro_export] macro_rules! x { ($id:ident, $file_name:literal, $code:expr, $companion_name:literal) => { const_attribute!($id, $file_name, $code, $companion_name); }; } // 批量生成全局常量 x!(USER_IO, "user_info.txt", 64, "user_companion.txt"); x!(USER_IO_1, "user_info_1.txt", 65, "user_companion_1.txt"); x!(USER_IO_2, "user_info_2.txt", 66, "user_companion_2.txt"); x!(USER_IO_3, "user_info_3.txt", 67, "user_companion_3.txt"); x!(USER_IO_4, "user_info_4.txt", 68, "user_companion_4.txt"); x!(USER_IO_5, "user_info_5.txt", 69, "user_companion_5.txt"); x!(USER_IO_6, "user_info_6.txt", 70, "user_companion_6.txt"); x!(USER_IO_7, "user_info_7.txt", 71, "user_companion_7.txt"); x!(USER_IO_8, "user_info_8.txt", 72, "user_companion_8.txt"); fn main() { // 测试输出,格式和原C++一致 println!( "{} --> {} --> {} --> {}", USER_IO_1.id, USER_IO_1.attribute_type.file_name, USER_IO_1.attribute_type.code, USER_IO_1.attribute_type.companion_name ); println!( "{} --> {} --> {} --> {}", USER_IO_2.id, USER_IO_2.attribute_type.file_name, USER_IO_2.attribute_type.code, USER_IO_2.attribute_type.companion_name ); println!( "{} --> {} --> {} --> {}", USER_IO_3.id, USER_IO_3.attribute_type.file_name, USER_IO_3.attribute_type.code, USER_IO_3.attribute_type.companion_name ); }
关键说明
- 编译期保证:所有常量用
const关键字声明,结构体字段使用&'static str(编译期嵌入的静态字符串),确保对象在编译阶段就完成初始化,无运行时开销。 - 宏的作用:
const_attribute!宏负责生成单个全局常量,x!宏是简化调用的包装,和原C++的宏逻辑完全对应。 - 结构清晰:结构体定义明确展示了对象的属性结构,宏展开后的代码可以通过
cargo expand命令查看,直观验证生成的常量。
内容的提问来源于stack exchange,提问作者kishoredbn
相关产品推荐
相关产品推荐

