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

玩转 Go 表达式引擎:expr 实战指南

玩转 Go 表达式引擎:expr 实战指南

在日常开发中,我们经常需要处理动态表达式计算、业务规则判断等场景。Go 标准库虽然提供了模板引擎的条件判断,但面对复杂逻辑时显得力不从心。今天要介绍的 expr 库,正是为解决这类问题而生的轻量级表达式引擎。

什么是 expr?

expr 是一个高性能的 Go 表达式引擎,它允许你在代码中安全地执行动态生成的表达式。其语法接近 Go 语言,支持变量访问、函数调用、逻辑运算等,非常适合以下场景:

  • 动态业务规则判断
  • 配置化条件过滤
  • 模板中的动态计算
  • 复杂逻辑的动态执行

快速入门:第一个 expr 程序

先从最简单的表达式计算开始,比如计算 1+10 的结果:

package mainimport ("fmt""github.com/expr-lang/expr"
)func main() {// 定义表达式code := "1 + 10"// 直接执行表达式(无需环境变量)result, err := expr.Eval(code, nil)if err != nil {panic(err)}fmt.Println(result) // 输出:11
}

这段代码展示了 expr 的核心用法:通过 expr.Eval() 函数直接执行表达式字符串,第一个参数是表达式,第二个参数是执行环境(可以是结构体、map 等)。

访问数据:从简单到复杂

expr 最强大的功能之一是能够访问外部数据,支持多种数据类型和嵌套结构。

1. 访问结构体字段

type User struct {Name stringAge  int
}func main() {user := User{Name: "Alice", Age: 25}// 表达式访问结构体字段code := `Name == "Alice" && Age > 18`result, _ := expr.Eval(code, user)fmt.Println(result) // 输出:true
}

注意:结构体字段必须首字母大写(导出字段),否则 expr 无法访问(受 Go 反射机制限制)。

2. 访问 Map 键值

func main() {data := map[string]interface{}{"product": "phone","price":   3999,}// 两种访问方式等价code := `product == "phone" && .price > 3000`result, _ := expr.Eval(code, data)fmt.Println(result) // 输出:true
}

3. 访问嵌套结构

对于嵌套的结构体或 Map,使用 . 符号链式访问:

func main() {data := map[string]interface{}{"user": map[string]interface{}{"name": "Bob","address": map[string]interface{}{"city": "Beijing",},},}// 访问嵌套 Map 的属性code := `user.name == "Bob" && user.address.city == "Beijing"`result, _ := expr.Eval(code, data)fmt.Println(result) // 输出:true
}

4. 处理切片和数组

结合 len() 函数可以方便地处理切片:

func main() {data := map[string]interface{}{"tags": []string{"go", "expr", "template"},}// 判断切片长度并访问元素code := `len(tags) == 3 && tags[0] == "go"`result, _ := expr.Eval(code, data)fmt.Println(result) // 输出:true
}

高级特性:让表达式更强大

1. 空安全访问

当访问可能为 nil 的字段时,使用 ?. 避免 panic:

code := `user?.address?.city == "Shanghai"`
// 如果 user 或 address 为 nil,表达式返回 false 而非错误

2. 自定义函数

expr 支持注册自定义函数,扩展表达式能力:

func main() {// 定义自定义函数:计算平方square := func(x int) int {return x * x}// 注册函数并执行表达式env := map[string]interface{}{"square": square,"num":    5,}code := `square(num) == 25`result, _ := expr.Eval(code, env)fmt.Println(result) // 输出:true
}

3. 编译优化

对于需要多次执行的表达式,先编译再执行可以提升性能:

func main() {code := `a + b * c`data := map[string]int{"a": 1, "b": 2, "c": 3}// 编译表达式program, _ := expr.Compile(code, expr.Env(data))// 多次执行(适合循环场景)for i := 0; i < 3; i++ {result, _ := expr.Run(program, data)fmt.Println(result) // 均输出:7}
}

结合模板引擎:动态渲染内容

虽然 expr 不是模板引擎,但可以与 Go 标准模板配合,实现动态内容渲染:

package mainimport ("os""text/template""github.com/expr-lang/expr"
)func main() {// 定义包含表达式的模板tplContent := `计算结果:{{calc "a + b * 2"}}判断结果:{{if calc "a > 10"}}a 大于 10{{else}}a 不大于 10{{end}}`// 准备数据data := map[string]int{"a": 5, "b": 3}// 创建模板并注册 calc 函数tpl := template.New("test").Funcs(template.FuncMap{"calc": func(exprCode string) (interface{}, error) {return expr.Eval(exprCode, data)},})// 解析并执行模板tpl.Parse(tplContent)tpl.Execute(os.Stdout, nil)
}

输出结果:

	计算结果:11判断结果:a 不大于 10

总结

expr 作为一款轻量级表达式引擎,以其接近 Go 的语法、良好的性能和丰富的特性,成为处理动态表达式场景的理想选择。无论是简单的数值计算,还是复杂的业务规则判断,expr 都能胜任。

通过本文介绍的基础用法和高级特性,相信你已经掌握了 expr 的核心能力。在实际项目中,还可以结合配置文件、数据库存储等方式,实现更灵活的动态规则系统。

如果你需要处理复杂的业务规则引擎场景,expr 绝对值得一试!

http://www.dtcms.com/a/515261.html

相关文章:

  • 【IO多路转接】高并发服务器实战:Reactor 框架与 Epoll 机制的封装与设计逻辑
  • 企业网站建设毕业设计论文龙岗网站建设开发设计公司
  • 力扣热题100道之238除自身以外数组的乘积
  • 把AI装进OS、批量落地智慧服务,智能手机革命2.0来了
  • 防爆手机可以通过普通智能手机改装吗?
  • 宇树H2仿生机器人登场
  • 语音识别技术之FireRedASR
  • 有什么指标可以判断手机是否降频
  • 禾赛科技与广和通战略合作,联合推出机器人解决方案加速具身智能商业化落地
  • 石家庄网站开发哪家好企业网站建设网站模板
  • Z3 Technology-适用于无人机和机器人的 4K 高清摄像机和视频编码器
  • 济南天桥区做网站的怎样做app推广
  • 建设河南网站外贸网站建设盲区
  • 运维逆袭志·第4期 | 安全风暴的绝地反击 :从告警地狱到智能防护
  • Java-集合求差集,如果B集合中的id在A集合中存在就移除,如果不在就返回A集合
  • 微服务即时通讯系统——整体架构和组件(1)
  • WPF入门
  • WPF布局控件(界面骨架核心)
  • WPF 常用样式属性及示例笔记
  • 【WPF】自定义颜色拾取器
  • MahApps.Metro WPF 开发使用过程中遇到的问题 - 未能加载文件或程序集“Microsoft.Xaml.Behaviors,
  • 【普中Hi3861开发攻略--基于鸿蒙OS】-- 第 26 章 WIFI实验-AP 建立网络
  • ARM架构深度解析:ARMv7、ARMv8、ARMv9的技术演进、芯片实现与未来展望
  • 线下剧本杀预约小程序核心功能玩法解析:轻量化载体重构娱乐消费生态
  • 【矩阵分析与应用】【第8章 特征分析】【8.3 凯莱-哈密顿定理求解矩阵高次幂详解】
  • 合肥制作企业网站免费收录网站推广
  • 阿里云安装docker-compose
  • Centos 7 :VMware Tools 启动脚本未能在虚拟机中成功运行
  • 基于vue的停车场管理系统
  • 短剧小程序系统开发:开启影视娱乐新纪元