引言
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的库,可以让我们在业务实现的时候更加的灵活。