如何通过过滤函数名称为条目打标签并自动管理函数列表
解决方案
问题1:获取正确的函数名称
std::stringify!只能处理编译期的变量名,循环里的变量adf不管指向哪个函数,它都只会输出"adf"。解决办法是把函数指针和对应的名称字符串绑定在一起,用元组或自定义结构体存储两者的关联关系。
问题2:自动维护过滤函数列表
手动添加函数到数组太繁琐,可以用Rust宏自动注册过滤函数,同时生成一个静态的函数列表,新增函数时只需要调用宏即可,不用手动修改数组。
下面是修改后的完整代码:
#[derive(Clone, Copy)] struct Bs; // 定义过滤函数的类型别名,简化代码 type FilterFn = fn(Bs) -> bool; // 宏:自动注册过滤函数并生成静态列表 macro_rules! register_filter { ($($name:ident),*) => { static FILTERS: &[(&'static str, FilterFn)] = &[ $( (stringify!($name), $name), )* ]; }; } // 定义过滤函数 fn adf(_bs: Bs) -> bool { true } fn bodens(_bs: Bs) -> bool { false } // 注册所有过滤函数,新增函数时直接加在这里即可 register_filter!(adf, bodens); struct MyTagger; impl MyTagger { fn from_tree(&self, tree: Vec<Bs>) -> Vec<String> { let mut res = Vec::new(); for path in tree { // 遍历静态过滤列表 for (name, filter) in FILTERS.iter() { if filter(path) { res.push(name.to_string()); } } } res } }
代码说明
- 函数名称绑定:通过
(函数名字符串, 函数指针)的元组,直接存储函数的真实名称,调用时直接取出即可,彻底避免stringify!的局限。 - 自动注册宏:
register_filter!宏会把传入的所有函数转换成(名称, 指针)的形式,并存到静态数组FILTERS里。新增过滤函数时,只需要在宏的参数里加上函数名,无需手动修改数组。 - 静态数组优势:静态数组在编译期就确定,运行时不需要动态创建Vec,性能更优。
内容的提问来源于stack exchange,提问作者eguneys
相关产品推荐
相关产品推荐

