golang任意Go表达式动态求值插件库goval的使用
golang任意Go表达式动态求值插件库goval的使用
goval是一个允许程序评估任意算术/字符串/逻辑表达式的Go库,支持访问变量和调用自定义函数。该项目已经稳定并用于生产系统,采用MIT许可证。
安装和使用
安装
go get -u github.com/maja42/goval
基本示例
package main
import (
"fmt"
"github.com/maja42/goval"
)
func main() {
// 创建评估器
eval := goval.NewEvaluator()
// 评估简单表达式
result, err := eval.Evaluate(`42 > 21`, nil, nil) // 返回 <true, nil>
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
变量访问示例
package main
import (
"fmt"
"github.com/maja42/goval"
)
func main() {
eval := goval.NewEvaluator()
// 定义变量
variables := map[string]interface{}{
"uploaded": 146,
"total": 400,
}
// 使用变量评估表达式
result, err := eval.Evaluate(`uploaded * 100 / total`, variables, nil) // 返回 <36, nil>
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
自定义函数示例
package main
import (
"fmt"
"github.com/maja42/goval"
"runtime"
)
func main() {
eval := goval.NewEvaluator()
// 定义变量
variables := map[string]interface{}{
"os": runtime.GOOS,
"arch": runtime.GOARCH,
}
// 定义自定义函数
functions := make(map[string]goval.ExpressionFunction)
functions["strlen"] = func(args ...interface{}) (interface{}, error) {
str := args[0].(string)
return len(str), nil
}
// 使用自定义函数评估表达式
result, err := eval.Evaluate(`strlen(arch[:2]) + strlen("text")`, variables, functions) // 返回 <6, nil>
if err != nil {
fmt.Println("Error:", err)
return
}
fmt.Println("Result:", result)
}
正则表达式匹配示例
package main
import (
"fmt"
"github.com/maja42/goval"
"regexp"
)
func main() {
eval := goval.NewEvaluator()
// 定义正则匹配函数
functions := make(map[string]goval.ExpressionFunction)
functions["matches"] = func(args ...interface{}) (interface{}, error) {
str := args[0].(string)
exp := args[1].(string)
reg := regexp.MustCompile(exp)
return reg.MatchString(str), nil
}
// 使用正则函数评估表达式
result1, err := eval.Evaluate(`matches("text", "[a-z]+")`, nil, functions) // 返回 <true, nil>
result2, err := eval.Evaluate(`matches("1234", "[a-z]+")`, nil, functions) // 返回 <false, nil>
fmt.Println("Result1:", result1)
fmt.Println("Result2:", result2)
}
支持的类型
goval完全支持以下类型:
nil
bool
int
float64
string
[]interface{}
(数组)map[string]interface{}
(对象)
在表达式中,int
和float64
都有number
类型并且可以透明地相互转换。
运算符
goval支持多种运算符,包括算术、逻辑、位运算等。运算符优先级严格遵循C/C++规则。
算术运算符示例
3 + 4 // 7
2 + 2 * 3 // 8
2 * 3 + 2.5 // 8.5
12 - 7 - 5 // 0
24 / 10 // 2
24.0 / 10 // 2.4
2 ** 4 // 16 (幂运算)
10 % 3 // 1
逻辑运算符示例
true && true // true
false || false // false
!true // false
42 > 21 // true
"a" == "a" // true
三元运算符示例
true ? 1 : 2 // 1
false ? 1 : 2 // 2
替代库
如果你正在寻找通用的评估库,也可以考虑Knetic/govaluate。goval与其主要区别包括:
- 更直观的语法
- 无中间AST - 解析和评估一步完成
- 更好的类型支持
- 更多运算符
- 十六进制字面量
- 数组和对象字面量
- 有用的错误信息
- 高度优化的解析器代码
- 高测试覆盖率
goval是一个功能强大且易于使用的表达式评估库,特别适合需要动态评估表达式的场景。
更多关于golang任意Go表达式动态求值插件库goval的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html
1 回复