You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何按需生成evalexpr上下文以匹配自定义结构体规则?

解决evalexpr处理大结构体仅转换规则用到字段的方案
  • 先解析表达式提取目标字段
    利用evalexpr的AST解析能力,先对用户编写的规则表达式做静态分析,提取其中引用的所有字段名。通过evalexpr::build_operator_tree生成抽象语法树后,递归遍历AST节点收集所有标识符(即结构体字段),这样就能精准定位规则用到的字段,不用处理全部60个。

  • 动态生成精简版上下文
    基于提取到的字段名,通过反射工具(比如serde或reflect crate)从CustomStruct实例中动态取出对应字段的值,转换为evalexpr兼容的Value类型后,再放入HashMapContext。示例代码如下:

    use evalexpr::{Value, HashMapContext};
    use serde::Serialize;
    use std::collections::HashMap;
    
    #[derive(Serialize)]
    struct CustomStruct {
        // 模拟60个字段
        field_x: i32,
        field_y: f64,
        nested_field: NestedStruct,
        // ...其他字段
    }
    
    #[derive(Serialize)]
    struct NestedStruct {
        sub_field: String,
    }
    
    // 解析表达式提取字段名
    fn extract_used_fields(expr: &str) -> Vec<String> {
        let tree = evalexpr::build_operator_tree(expr).unwrap();
        let mut fields = Vec::new();
        // 递归遍历AST收集标识符
        fn traverse(node: &evalexpr::Node, fields: &mut Vec<String>) {
            match node {
                evalexpr::Node::Identifier(id) => fields.push(id.to_string()),
                evalexpr::Node::Operator(_, children) => {
                    for child in children {
                        traverse(child, fields);
                    }
                }
                _ => {}
            }
        }
        traverse(&tree, &mut fields);
        fields.dedup();
        fields
    }
    
    // 构建仅包含目标字段的上下文
    fn build_target_context(inst: &CustomStruct, fields: &[String]) -> HashMapContext {
        let mut context = HashMapContext::new();
        // 用serde将结构体转为通用JSON对象,按需提取字段
        let obj = serde_json::to_value(inst).unwrap().as_object().unwrap();
        for field in fields {
            if let Some(val) = obj.get(field) {
                let eval_val = Value::from_json(val).unwrap();
                context.set_value(field.clone(), eval_val).unwrap();
            }
        }
        context
    }
    
  • 适配复杂类型转换
    针对嵌套结构体、枚举等复杂类型,提前定义好对应的Value转换逻辑——比如嵌套结构体转为Value::Object,枚举转为字符串或数值表示,确保evalexpr能正确解析这些类型的字段值。

  • 缓存优化性能
    若同一条规则会重复执行,缓存提取到的字段名列表,避免每次都重新解析表达式,减少不必要的开销。

内容的提问来源于stack exchange,提问作者JoL

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 01:52:05