govaluateevalgovaluate
快速使用
安装
$ go get github.com/Knetic/govaluate
使用
package main
import (
"fmt"
"github.com/Knetic/govaluate"
"log"
)
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)
}
govaluate
NewEvaluableExpression()Evaluate
govaluate10 > 0Evaluate()nil10 > 0govaluate
参数
govaluateEvaluate()map[string]interface{}map
package main
import (
"fmt"
"github.com/Knetic/govaluate"
)
func main() {
expr1, _ := govaluate.NewEvaluableExpression("foo >0")
param:= make(map[string]interface{})
param["foo"] = -1
r1, _ := expr1.Evaluate(param)
fmt.Printf("r1:%+v\n",r1)
expr2, _ := govaluate.NewEvaluableExpression("a * b")
param1 := make(map[string]interface{})
param1["a"] = 2
param1["b"] =4
r2,_:= expr2.Evaluate(param1)
fmt.Printf("r2:%+v",r2)
expr3, _ := govaluate.NewEvaluableExpression("(a / b) * 100")
param3 := make(map[string]interface{})
param3["a"] = 1024
param3["b"] = 512
r3,_:= expr3.Evaluate(param3)
fmt.Printf("r3:%+v",r3)
}
一次编译,多次运行
Evaluate()
package main
import (
"fmt"
"github.com/Knetic/govaluate"
)
func main() {
expr2, _ := govaluate.NewEvaluableExpression("a * b")
param1 := make(map[string]interface{})
param1["a"] = 2
param1["b"] =4
r2,_:= expr2.Evaluate(param1)
fmt.Printf("r2:%+v",r2)
param2 := make(map[string]interface{})
param2["a"] = 5
param2["b"] =6
r23,_:= expr2.Evaluate(param2)
fmt.Printf("r223:%+v",r23)
}
上面的代码的运行结果,第一次运行 根据传递的参数得到的结果是8,第二次运行,由于我们更换了参数,但是还是复用了【a*b】的表达式,所以结果是30。
函数govaluategovaluatemap[string]govaluate.ExpressionFunctiongovaluate.NewEvaluableExpressionWithFunctions()func (args ...interface{}) (interface{}, error)
package main
import (
"fmt"
"github.com/Knetic/govaluate"
)
func main() {
funcs:= map[string]govaluate.ExpressionFunction{
"strlen":func(argus ...interface{})(interface{},error) {
len:= len(argus[0].(string))
return len,nil
},
}
exprString:="strlen('testing')"
expr, _ := govaluate.NewEvaluableExpressionWithFunctions(exprString, funcs)
r, _ := expr.Evaluate(nil)
fmt.Println(r)
}
strlenstrlen('teststring')strlenteststring
函数可以接受任意数量的参数,而且可以处理嵌套函数调用的问题。所以可以写出类似下面这种复杂的表达式:
sqrt(x1 ** y1, x2 ** y2)
max(someValue, abs(anotherValue), 10 * lastValue)
访问器
Accessors.govaluate.
package main
import (
"fmt"
"github.com/Knetic/govaluate"
)
type User struct {
FirstName string
LastName string
Age int
}
func (u User) FullName()string {
return u.FirstName + u.LastName
}
func main() {
u := User{FirstName: "go", LastName: "jack", Age: 18}
parameters := make(map[string]interface{})
parameters["u"] = u
expr, _ := govaluate.NewEvaluableExpression("u.FullName()")
result, _ := expr.Evaluate(parameters)
fmt.Println("user", result)
expr, _ = govaluate.NewEvaluableExpression("u.Age > 18")
result, _ = expr.Evaluate(parameters)
fmt.Println("age > 18?", result)
}
UserFullname()u.Fullname()
foo.SomeMap['key']mapu.Fullname()govaluate.ParametergovaluateGet()
// src/github.com/Knetic/govaluate/parameters.go
type Parameters interface {
Get(name string) (interface{}, error)
}
UserParameter
package main
import (
"errors"
"fmt"
"github.com/Knetic/govaluate"
)
type User struct {
FirstName string
LastName string
Age int
}
func (u User) FullName()string {
return u.FirstName + u.LastName
}
func (u User)Get(name string) (interface{},error) {
if name =="FullName" {
return u.FirstName + " " + u.LastName,nil
}
return nil,errors.New("unsupported field " + name)
}
func main() {
u := User{FirstName: "go", LastName: "jack", Age: 18}
expr1,_:=govaluate.NewEvaluableExpression("FullName")
rr,_:=expr1.Eval(u)
fmt.Println("user",rr)
}
Evaluate()map[string]interface{}Eval()ParameterEvaluate()Eval()
/ src/github.com/Knetic/govaluate/EvaluableExpression.go
func (this EvaluableExpression) Evaluate(parameters map[string]interface{}) (interface{}, error) {
if parameters == nil {
return this.Eval(nil)
}
return this.Eval(MapParameters(parameters))
}
ParameterGet()FullNameu.Get()
支持的操作和类型
govaluategovaluategovaluate
算数、比较和逻辑运算:
+-/*&|^**%>><<>>=<<===!==~!~=~!~||&&
常量:
govaluategovaluate'govaluatetruefalse
其他:
(),(1, 2, 'foo')govaluate[]interface{}? :
govaluate2014-01-022014-01-01 23:59:59time.Time
func main() {
expr, _ := govaluate.NewEvaluableExpression("'2014-01-02' > '2014-01-01 23:59:59'")
result, _ := expr.Evaluate(nil)
fmt.Println(result)
}
错误处理
govaluate
总结
govaluate虽然支持的类型和操作优先,但是对于一些需要通过前端页面传递参数生成判断表达式的场景还是能非常好的实现,所以多掌握一些golang的库,可以让我们在业务实现的时候更加的灵活。