govaluate库将字符串转换为表达式,类似于JavaScript中的eval功能。这对于在sql数据表中的保存表达式等是有用的。
go get github.com/Knetic/govaluate
不过我去看了,7年前更新。汗…. 试了,尚且能用。
另外一个 https://github.com/casbin/govaluate 似乎最近有维护,但未测试。
这个示例返回一个计算结果
package main
import (
"fmt"
"log"
"github.com/Knetic/govaluate"
)
func main() {
expr, err := govaluate.NewEvaluableExpression("10 > 0")
if err != nil {
log.Fatal("syntax error:", err)
}
result, err := expr.Evaluate(nil)
if err != nil {
log.Fatal("evaluate error:", err)
}
fmt.Println(result)
}
而对于经常的场景应该如下示例,传入一个变量参数
func main() {
expr, _ := govaluate.NewEvaluableExpression("foo > 0")
parameters := make(map[string]interface{})
parameters["foo"] = -1
result, _ := expr.Evaluate(parameters)
fmt.Println(result)
expr, _ = govaluate.NewEvaluableExpression("(requests_made * requests_succeeded / 100) >= 90")
parameters = make(map[string]interface{})
parameters["requests_made"] = 100
parameters["requests_succeeded"] = 80
result, _ = expr.Evaluate(parameters)
fmt.Println(result)
expr, _ = govaluate.NewEvaluableExpression("(mem_used / total_mem) * 100")
parameters = make(map[string]interface{})
parameters["total_mem"] = 1024
parameters["mem_used"] = 512
result, _ = expr.Evaluate(parameters)
fmt.Println(result)
}
这样将表达式存入sql,然后在代码中替换变量的值即可使用。第一个返回的值为true/false,第二个返回值为计算结果。
符号的处理
通过转义符:将名称用[]包裹,或用\转义
func main() {
expr, _ := govaluate.NewEvaluableExpression("[response-time] < 100")
parameters := make(map[string]interface{})
parameters["response-time"] = 80
result, _ := expr.Evaluate(parameters)
fmt.Println(result)
expr, _ = govaluate.NewEvaluableExpression("response\\-time < 100")
parameters = make(map[string]interface{})
parameters["response-time"] = 80
result, _ = expr.Evaluate(parameters)
fmt.Println(result)
}
甚至它还能保存函数
也就是将函数功能保存在字符串(sql)中,然后程序调用? 没实际测试。
那是不是可以将函数功能保存在授权文件中,若授权文件不能正确解码,可以导致程序无法运行?(用于加解密)
func main() {
functions := map[string]govaluate.ExpressionFunction{
"strlen": func(args ...interface{}) (interface{}, error) {
length := len(args[0].(string))
return length, nil
},
}
exprString := "strlen('teststring')"
expr, _ := govaluate.NewEvaluableExpressionWithFunctions(exprString, functions)
result, _ := expr.Evaluate(nil)
fmt.Println(result)
}