# comp **Repository Path**: zhenghexcs/comp ## Basic Information - **Project Name**: comp - **Description**: comp 是一个用于解析和计算字符串表达式的 Go 语言库。它支持基本的数学运算符、自定义函数以及对象属性访问。 - **Primary Language**: Go - **License**: BSD-4-Clause - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2023-03-24 - **Last Updated**: 2025-09-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: comp, expression, 计算, 解析器 ## README # comp `comp` 是一个用于解析和计算字符串表达式的 Go 语言库。它支持基本的数学运算符、自定义函数以及对象属性访问,适合在业务规则、公式计算等场景下使用。 ## 核心功能 ### 入口函数 - **`comp.NewCompNode(exp string) *CompNode`** - 解析输入的字符串表达式 `exp`,生成一个计算节点树(`CompNode`)。 - 支持的运算符包括:`+`, `-`, `*`, `/`, `%`。 - 支持自定义函数和对象属性访问。 ### 计算表达式值 - **`CompNode.CompVal(et *CompEvent) int64`** - 递归计算节点树的值。 - 需要传入 `CompEvent`,用于提供变量和对象属性的上下文。 ### 自定义函数 - **`comp.RegisterComp(name string, f CompMark)`** - 注册自定义运算符或函数。 - `f` 是一个实现了 `CompMark` 签名的函数。 ### 对象属性访问 - 支持通过 `对象名.属性名` 的方式访问对象属性。例如 `self.ID`。 - 需要实现 `IAttr` 接口,并通过 `comp.NewObjectAttr("self", obj)` 注册到 `CompEvent.ObjList`。 ## 安装 使用 `go get` 安装: ```bash go get gitee.com/zhenghexcs/comp ``` ## 快速开始 以下是一个简单的使用示例: ```go package main import ( "fmt" "gitee.com/zhenghexcs/comp" ) type SelfObj struct{} func (obj *SelfObj) GetAttr(attr string) int64 { if attr == "ID" { return 10 } return 0 } func main() { // 定义表达式 expression := "(a+b*c-4)/self.ID" // 解析表达式 node := comp.NewCompNode(expression) // 定义上下文 obj := &SelfObj{} event := &comp.CompEvent{ ObjList: []comp.Iobject{comp.NewObjectAttr("self", obj)}, Param: []int64{10, 2, 7}, // a=10, b=2, c=7 } // 计算表达式值 result := node.CompVal(event) // 输出结果 fmt.Println("Result:", result) // 输出: Result: 2 } ``` ## 进阶用法 ### 注册自定义函数 ```go comp.RegisterComp("max", func(node *comp.CompNode, et *comp.CompEvent) int64 { val1 := node.Num1.CompVal(et) val2 := node.Num2.CompVal(et) if val1 > val2 { return val1 } return val2 }) expr := "max(a, b) + c" node := comp.NewCompNode(expr) event := &comp.CompEvent{Param: []int64{5, 10, 3}} // a=5, b=10, c=3 fmt.Println(node.CompVal(event)) // 输出: 13 ``` ### 变量与参数映射 - 表达式中的变量名如 `a`, `b`, `c`,会按顺序映射到 `CompEvent.Param` 的第 0、1、2 个元素。 - 变量名区分大小写,且仅支持单字母变量。 ### 对象属性访问 - 通过 `对象名.属性名` 访问对象属性。 - 需实现 `IAttr` 接口,并用 `comp.NewObjectAttr` 注册到 `CompEvent.ObjList`。 ### 支持的表达式示例 - `a+b*c-4` - `(a+b)*c` - `self.ID + a` - `max(a, b) + c` ## API 说明 ### CompNode - `CompNode.CompVal(et *CompEvent) int64`:计算表达式的值。 - `CompNode.String() string`:返回表达式的结构字符串。 ### CompEvent - `ObjList []Iobject`:对象列表,支持属性访问。 - `Param []int64`:变量参数列表。 ### Iobject/IAttr - `GetObjName() string`:返回对象名。 - `GetAttr(attrname string) int64`:返回属性值。 ## 代码结构 - `CompNode.go`:核心计算节点的定义和解析逻辑。 - `CompEvent.go`:计算上下文的定义,包括变量和对象属性。 - `StringBuilder.go`:字符串构建工具类。 - `string.go`:字符串操作工具类。 - `Iobject.go`:对象接口定义,用于支持对象属性访问。 ## 注意事项 - 仅支持整数类型的计算,所有结果均为 `int64`。 - 变量名仅支持单字母(如 a, b, c)。 - 表达式语法不支持括号嵌套超过函数参数的情况。 - 自定义函数目前仅支持两个参数。 ## 测试与基准 可参考 `test/comp_test.go`,包含丰富的单元测试和基准测试。 ### 基准测试报告 以下是运行基准性能测试的输出: ```plaintext goos: windows goarch: amd64 pkg: gitee.com/zhenghexcs/comp/test cpu: 12th Gen Intel(R) Core(TM) i5-12400F BenchmarkBasicExpressionEvaluation BenchmarkBasicExpressionEvaluation-12 47096499 23.89 ns/op 0 B/op 0 allocs/op BenchmarkCustomFunction BenchmarkCustomFunction-12 75076953 14.02 ns/op 0 B/op 0 allocs/op BenchmarkSimpleMathExpression BenchmarkSimpleMathExpression-12 140195186 8.705 ns/op 0 B/op 0 allocs/op BenchmarkSimpleMathExpressionNative BenchmarkSimpleMathExpressionNative-12 1000000000 0.1324 ns/op 0 B/op 0 allocs/op PASS ok gitee.com/zhenghexcs/comp/test 4.944s ``` ## 贡献 欢迎提交 Issue 和 Pull Request 来改进此库。 ## License BSD 4-Clause License