Git Product home page Git Product logo

goexpression's Introduction

goexpression 轻量级go表达式执行引擎

一、操作符

  • 三元/二元操作符:

    • ? :
    • 逻辑操作符: ||、&&
    • 比较操作符: ==、!=、<、<=、>、>=、in。
    • 计算操作符: +、-、*、/、%、**
    • 位运算操作符: |、^、&、&^、<<、>>
  • 一元操作符:

    • 自增: ++, 注意自增与自减只支持前缀, eg: ++2, 而2++是不被允许的, 因为表达式引擎只是运行一个表达式, 后缀的自增自减毫无意义
    • 自减: --
    • 取反: !
    • 位取反: ~
    • 负: -
  • 注:

    • 操作符优先级与Go语言操作符优先级一致(如果运算符相同的话)
    • 按位取反位~而不是Go中的^
    • 相对于Go增加 in 、** 两个操作符。
      • 其中 in 操作符用于判断某值是否在一个集合中, eg: 1 in [1, 2.0, '3_'], 可以看到集合中元素的类型可以不一样, 其中集合可以只含有一个元素, 但也需要用 [ ]包围
      • ** 为幂运算操作符, eg: 2 ** 3 的值为8

二、字面量: 支持三种字面量

  • 数值: 表达式中所有数值使用go中的float64表示, 数值书写可以写成1、1.0等都是允许的, 数值只支持10进制, 且不支持指数的表示方式
  • 布尔: 书写为 true、false、t、f或四者的部分或全部大写都是可以的
  • 字符串: 用小引号包裹, eg: 'go_expression', 支持转义。特别的, 如要表示小引号需要转义。

三、支持变量与函数调用

  • 为了代码简洁, 传入的参数以及函数返回值如果为数值的话, 一律写作float64格式, 否则表达式执行将有可能不符合预期 如下代码所示
exp1, _ := goexpression.NewExpression("b(c, d) == a", true, map[string]goexpression.Function{
    "b": func(params ...any) (any, error) {
        if len(params) != 2 {
            return nil, fmt.Errorf("error")
        }
        return params[0].(float64) + params[1].(float64), nil
    },
})
// 为了性能, 表达式一次编译, 多次运行, 使用方需要实现表达式缓存, key为原始表达式, value 为 goexpression.NewExpression
_, _ = exp1.Execute(map[string]any{
	 "a": float64(100.0),
	 "c": float64(50.0),
	 "d": float64(50.0),
})

四、注意事项

  • 显然的, 可以嵌套调用, 形如b1(b2(b3())) && 1 in [num1(), num2()] 这样的表达式都是接受的
  • 为了性能提升, 最好一次编译, 多次运行。即NewExpression方法调用之后, 得到的表达式可以传入不同的参数多次运行
  • 表达式除了可以返回bool、string、float64 (三者也提供了转换函数)。还可以返回[]any切片, 即表达式只包含 "[item1, item2, ....]" 这种情况, 但是应该极少用到, 所以没有提供转换函数, 如有需求可以自行转换
  • 注意变量在运算过程中是否改变, 不同使用场景有不同结果:
    • 场景1: ++a == 1 && a == 2。注意, 此时如果执行时传入a的值为0, 那么 ++a == 1将为true, 但是当运行到 a == 2时, a还是等于0, 这有点反直觉, 当然也可以优化, 目前暂时不优化
    • 场景2: func1(a) == 1 && func2(a) == 2, 如果a为非值类型, 比如是个map, 那么func1中对a的操作func2将会感知到, 这需要使用者知道

五、待优化点

  • 报错信息尤其是运算时期的报错只直接指明了类型错误, TODO: 优化语法分析阶段与执行阶段的报错信息

goexpression's People

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.