当前位置: 首页 > ops >正文

go的工具库:github.com/expr-lang/expr

github.com/expr-lang/expr 是一个 Go 语言的表达式求值库,它允许你在运行时安全地执行表达式。主要用途包括:

1.表达式求值:

program, err := expr.Compile("2 + 2")
if err != nil {// 处理错误
}
result, err := expr.Run(program, nil)
// result 将是 4

2.条件表达式

program, err := expr.Compile("age > 18 && name == 'John'")
if err != nil {// 处理错误
}
result, err := expr.Run(program, map[string]interface{}{"age": 20,"name": "John",
})
// result 将是 true

3.复杂表达式

program, err := expr.Compile("sum(numbers) > 100 && len(numbers) > 0")
if err != nil {// 处理错误
}
result, err := expr.Run(program, map[string]interface{}{"numbers": []int{1, 2, 3, 4, 5},"sum": func(numbers []int) int {sum := 0for _, n := range numbers {sum += n}return sum},
})

主要特点:
安全性:表达式在沙箱环境中执行
性能:编译后的表达式执行速度快
灵活性:支持自定义函数和变量
类型安全:支持类型检查

常见用途:
规则引擎
配置验证
动态条件判断
数据过滤
业务规则执行
例如,在配置验证中:

type Config struct {MaxSize intMinSize int
}config := Config{MaxSize: 100, MinSize: 10}
program, err := expr.Compile("MaxSize > MinSize")
if err != nil {// 处理错误
}
result, err := expr.Run(program, config)
if err != nil {// 处理错误
}
if !result.(bool) {// 配置无效
}

在业务规则中:

type Order struct {Amount float64Items  int
}order := Order{Amount: 100, Items: 5}
program, err := expr.Compile("Amount > 50 && Items > 0")
if err != nil {// 处理错误
}
result, err := expr.Run(program, order)
if err != nil {// 处理错误
}
if result.(bool) {// 订单有效
}

使用注意事项

expr.Compile 方法的性能和使用注意事项如下:
1.编译性能:

// 编译性能
program, err := expr.Compile("2 + 2")

编译时间通常很短,在微秒级别
但对于复杂表达式,编译时间会相应增加
建议缓存编译结果,避免重复编译

2.缓存编译结果:

// 使用 sync.Map 缓存编译结果
var compiledExpressions sync.Mapfunc getCompiledExpression(expr string) (*expr.Program, error) {// 先查找缓存if cached, ok := compiledExpressions.Load(expr); ok {return cached.(*expr.Program), nil}// 编译新表达式program, err := expr.Compile(expr)if err != nil {return nil, err}// 存入缓存compiledExpressions.Store(expr, program)return program, nil
}

3.错误处理:

// 完整的错误处理
program, err := expr.Compile("invalid expression")
if err != nil {switch e := err.(type) {case *expr.Error:// 处理表达式错误log.Printf("Expression error: %v", e)default:// 处理其他错误log.Printf("Unexpected error: %v", e)}return
}

4.类型安全:

// 使用类型检查
env := map[string]interface{}{"age": 20,"name": "John",
}// 编译时进行类型检查
program, err := expr.Compile("age > 18 && name == 'John'", expr.Env(env))
if err != nil {// 处理类型错误return
}

5.并发安全:

// 使用互斥锁保护缓存
var (cache     = make(map[string]*expr.Program)cacheLock sync.RWMutex
)func getCompiledExpression(expr string) (*expr.Program, error) {cacheLock.RLock()if program, ok := cache[expr]; ok {cacheLock.RUnlock()return program, nil}cacheLock.RUnlock()cacheLock.Lock()defer cacheLock.Unlock()program, err := expr.Compile(expr)if err != nil {return nil, err}cache[expr] = programreturn program, nil
}
http://www.xdnf.cn/news/11855.html

相关文章:

  • 杰发科技AC7840——Timer修改重装载值
  • 深入解析Java17核心新特性(增强NullPointerException、强封装 JDK 内部 API、伪随机数生成器增强)
  • LVDS与GMSL和FPD-Link之间的关系
  • CppCon 2015 学习:All Your Tests are Terrible
  • Unity 中实现可翻页的 PageView
  • 【游戏科学】游戏开发中数学算法的核心与应用
  • Opencl
  • superior哥AI系列第9期:高效训练与部署:从实验室到生产环境
  • 【Linux】centos软件安装
  • ios版本的Tiktok二次安装不上,提示:Unable to Install “TikTok”
  • Android apk装机编译类型: verify、speed-profile, speed与启动耗时
  • 【学习记录】如何使用 Python 提取 PDF 文件中的内容
  • 聚沙成塔,三步成书:GitBook极简入门教程
  • 近期调试有感
  • 快速掌握MCP——Spring AI MCP包教包会
  • 01串(二进制串)与集合之间存在天然的对应关系 ← bitset
  • django ssh登录 并执行命令
  • 3373. 连接两棵树后最大目标节点数目 II
  • [论文阅读]PPT: Backdoor Attacks on Pre-trained Models via Poisoned Prompt Tuning
  • 【推荐算法】Embedding+MLP:TensorFlow实现经典深度学习推荐模型详解
  • Openlayers从入门到入坟
  • 第五期书生大模型实战营-《L1G1-玩转书生大模型 API 之 Browser-Use 实践》
  • OpenCV 键盘响应来切换图像
  • c++中char *p指针指向字符串输出问题
  • 2025政务服务便民热线创新发展会议顺利召开,张晨博士受邀分享
  • MYSQL(二) ---MySQL 8.4 新特性与变量变更
  • 【C++】string类的模拟实现(详解)
  • Python 隐藏法宝:双下划线 _ _Dunder_ _
  • day027-Shell自动化编程-基础
  • 如何使用 BPF 分析 Linux 内存泄漏,Linux 性能调优之 BPF 分析内核态、用户态内存泄漏