formula

package module
v1.0.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2026 License: MIT Imports: 10 Imported by: 0

README

formula

github.com/OptLTD/library/formula

基于 expr-lang/expr公式计算模块,提供接近 Excel 语义的逻辑、数学、日期时间与文本函数,供业务规则与 search 等模块调用。

用途

  • 将扁平业务字段(如 basic.qty)映射为嵌套环境(FormulaEnv
  • 编译并执行公式字符串(Build / BuildWithOptions / ExprOptions
  • 内置 IF / IFS / SWITCHSUMMARGINALNOWDAYS 等函数
  • 预处理存量小写 if(IF(NormalizeExcelIFCalls

文件说明

文件 内容
build.go BuildBuildWithOptionsExprOptions
logic.go IFIFSSWITCH
math.go 数值运算、SUMMARGINAL
datetime.go NOWDAYSHOURSMINUTES
text.go 文本函数扩展点
env.go FormulaEnv
normalize.go 小写 if( 规范化

快速开始

import "github.com/OptLTD/library/formula"

combine := map[string]any{
    "basic.qty":   3.0,
    "basic.price": 100.0,
}
env := formula.FormulaEnv(combine)

total, err := formula.Build(`basic.qty * basic.price`, env)
// total == 300

level, err := formula.Build(
    `IFS(basic.qty >= 3, "bulk", basic.qty >= 1, "retail", true, "none")`,
    env,
)
// level == "bulk"

需要自定义 expr 选项或非默认行为时,使用 BuildWithOptionsExprOptions() 自行 expr.Compile / expr.Run

公式示例

IF(basic.qty > 1, 100, 0)
IFS(basic.qty >= 3, "bulk", basic.qty >= 1, "retail", true, "none")
SUM(1, 2, 3)
MARGINAL(350, [200, 400], [0.5, 0.6, 0.8])
DAYS(结束时间 - 开始时间)

注意事项

  • 逻辑函数请写 IF(...)(大写);expr 内置小写 if 是语法关键字,不是 Excel 风格函数
  • 存量小写 if( 可用 formula.NormalizeExcelIFCalls(raw) 预处理后再 Build
  • Build 对数值结果截断保留 3 位小数;字符串等非数值结果原样返回

完整示例见 example/demo/formula.go

测试

cd formula && go test ./...

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Build

func Build(code string, data map[string]any) (any, error)

Build 编译并执行公式;保留历史行为,并在非数值结果时返回原值。

func BuildWithOptions

func BuildWithOptions(code string, data map[string]any, extraOptions ...expr.Option) (any, error)

BuildWithOptions 编译并执行公式;支持附加 expr.Option(如注入自定义函数)。 数值结果会按既有规则做截断;非数值结果原样返回。

func ExprOptions

func ExprOptions() []expr.Option

ExprOptions 返回与 Build 相同的 expr 编译选项,供需要自定义 Run 流程的场景使用。

func FormulaEnv

func FormulaEnv(combine map[string]any) map[string]any

FormulaEnv 将 Combine 转为 expr 可用的环境:无点的键原样放入(map 值浅拷贝一层,避免合并点号键时改动 Combine);带点的键(如 demo.some)合并为嵌套 map,便于公式里写 demo.some。

func NormalizeExcelIFCalls

func NormalizeExcelIFCalls(expr string) string

NormalizeExcelIFCalls 把 Excel 风格的三参调用 if(…) / If(…) 统一成 IF(…),避免 expr 把小写 if 解析成关键字语法。 不会改写:sumif(、countif(、elseif(、以及 "if(" 若未来要做字符串字面量需另行处理。

Types

type DateTimeFuncs

type DateTimeFuncs struct{}

DateTimeFuncs 为无状态的日期时间类 expr 函数接收者。

type LogicFuncs

type LogicFuncs struct{}

LogicFuncs 为无状态的逻辑类 expr 函数接收者。

type MathFuncs

type MathFuncs struct{}

MathFuncs 为无状态的数学类 expr 函数接收者。

func (MathFuncs) CeilDecimal

func (f MathFuncs) CeilDecimal(num float64, decimal int) (float64, error)

CeilDecimal 舍弃的尾数不为 0 时强制进位。

func (MathFuncs) FloorDecimal

func (f MathFuncs) FloorDecimal(num float64, decimal int) (float64, error)

FloorDecimal 强制舍弃尾数(向负无穷)。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL