(摘) Go库:Govaluate字符串转换为表达式

声明:内容源自网络,版权归原作者所有。若有侵权请在网页聊天中联系我

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)
}

相关文章