package functions import ( "fmt" "regexp" "strconv" "strings" "sync" "github.com/expr-lang/expr" "github.com/expr-lang/expr/vm" "github.com/rulego/streamsql/utils/cast" ) // ExprBridge bridges StreamSQL function system with expr-lang/expr type ExprBridge struct { streamSQLFunctions map[string]Function exprProgram *vm.Program exprEnv map[string]interface{} mutex sync.RWMutex // Add read-write lock to protect concurrent access } // NewExprBridge creates new expression bridge func NewExprBridge() *ExprBridge { return &ExprBridge{ streamSQLFunctions: make(map[string]Function), // Initialize as empty, dynamically get exprEnv: make(map[string]interface{}), } } // RegisterStreamSQLFunctionsToExpr registers StreamSQL functions to expr environment func (bridge *ExprBridge) RegisterStreamSQLFunctionsToExpr() []expr.Option { bridge.mutex.Lock() defer bridge.mutex.Unlock() options := make([]expr.Option, 0) // Dynamically get all currently registered functions allFunctions := ListAll() // Register all StreamSQL functions to expr environment for name, fn := range allFunctions { // To avoid closure issues, use immediately executed function function := fn wrappedFunc := func(function Function) func(params ...interface{}) (interface{}, error) { return func(params ...interface{}) (interface{}, error) { ctx := &FunctionContext{ Data: bridge.exprEnv, } return function.Execute(ctx, params) } }(function) // Add function to expr environment bridge.exprEnv[name] = wrappedFunc // Register function type information options = append(options, expr.Function( name, wrappedFunc, )) } return options } // CreateEnhancedExprEnvironment creates enhanced expr execution environment func (bridge *ExprBridge) CreateEnhancedExprEnvironment(data map[string]interface{}) map[string]interface{} { bridge.mutex.RLock() defer bridge.mutex.RUnlock() // Merge data and function environment env := make(map[string]interface{}) // Add user data for k, v := range data { env[k] = v } // Dynamically get all currently registered functions allFunctions := ListAll() // Add all StreamSQL functions for name, fn := range allFunctions { // Ensure closure captures correct function instance function := fn wrappedFunc := func(function Function) func(params ...interface{}) (interface{}, error) { return func(params ...interface{}) (interface{}, error) { ctx := &FunctionContext{ Data: data, // Use current data context } return function.Execute(ctx, params) } }(function) // Register lowercase version env[name] = wrappedFunc // Register uppercase version env[strings.ToUpper(name)] = wrappedFunc } // Add some convenient math function aliases to avoid conflicts with built-ins env["streamsql_abs"] = env["abs"] env["streamsql_sqrt"] = env["sqrt"] env["streamsql_min"] = env["min"] env["streamsql_max"] = env["max"] // Add custom LIKE matching function env["like_match"] = func(text, pattern string) bool { return bridge.matchesLikePattern(text, pattern) } return env } // CompileExpressionWithStreamSQLFunctions 编译表达式,包含StreamSQL函数 func (bridge *ExprBridge) CompileExpressionWithStreamSQLFunctions(expression string, dataType interface{}) (*vm.Program, error) { options := []expr.Option{ expr.Env(dataType), } // 添加StreamSQL函数 streamSQLOptions := bridge.RegisterStreamSQLFunctionsToExpr() options = append(options, streamSQLOptions...) // 添加LIKE相关的自定义函数(只需要like_match,其他是内置操作符) options = append(options, expr.Function("like_match", func(params ...any) (any, error) { if len(params) != 2 { return false, fmt.Errorf("like_match function requires 2 parameters") } text, ok1 := params[0].(string) pattern, ok2 := params[1].(string) if !ok1 || !ok2 { return false, fmt.Errorf("like_match function requires string parameters") } return bridge.matchesLikePattern(text, pattern), nil }), ) // 启用一些有用的expr功能 options = append(options, expr.AllowUndefinedVariables(), // 允许未定义变量 expr.AsBool(), // 期望布尔结果(可根据需要调整) ) return expr.Compile(expression, options...) } // EvaluateExpression 评估表达式,自动选择最合适的引擎 func (bridge *ExprBridge) EvaluateExpression(expression string, data map[string]interface{}) (interface{}, error) { // 首先预处理反引号标识符 if bridge.ContainsBacktickIdentifiers(expression) { processedExpr, err := bridge.PreprocessBacktickIdentifiers(expression) if err == nil { expression = processedExpr } } // 检查是否包含LIKE操作符,如果有则进行预处理 if bridge.ContainsLikeOperator(expression) { processedExpr, err := bridge.PreprocessLikeExpression(expression) if err == nil { expression = processedExpr } } // 检查是否包含IS NULL或IS NOT NULL操作符,如果有则进行预处理 if bridge.ContainsIsNullOperator(expression) { processedExpr, err := bridge.PreprocessIsNullExpression(expression) if err == nil { expression = processedExpr } } // 检查是否包含字符串拼接模式 if bridge.isStringConcatenationExpression(expression, data) { result, err := bridge.evaluateStringConcatenation(expression, data) if err == nil { return result, nil } } // 尝试使用编译后的程序执行(包含StreamSQL函数) program, err := bridge.CompileExpressionWithStreamSQLFunctions(expression, data) if err == nil { // 创建增强环境 env := bridge.CreateEnhancedExprEnvironment(data) result, err := expr.Run(program, env) if err == nil { return result, nil } } // 如果编译失败,尝试直接使用expr.Eval env := bridge.CreateEnhancedExprEnvironment(data) result, err := expr.Eval(expression, env) if err != nil { // 检查是否是函数调用,如果是则不要回退到数值表达式处理 if bridge.isFunctionCall(expression) { return nil, fmt.Errorf("failed to evaluate function call '%s': %v", expression, err) } // 如果expr失败,回退到自定义expr系统(仅限数值计算) return bridge.fallbackToCustomExpr(expression, data) } return result, nil } // isStringConcatenationExpression 检查是否是字符串拼接表达式 func (bridge *ExprBridge) isStringConcatenationExpression(expression string, data map[string]interface{}) bool { // 如果表达式包含 + 操作符 if !strings.Contains(expression, "+") { return false } // 分析表达式中的操作数 parts := strings.Split(expression, "+") for _, part := range parts { part = strings.TrimSpace(part) // 如果包含字符串字面量(用引号包围) if (strings.HasPrefix(part, "'") && strings.HasSuffix(part, "'")) || (strings.HasPrefix(part, "\"") && strings.HasSuffix(part, "\"")) || part == "_" { return true } // 如果是字段引用,检查字段值是否为字符串 if value, exists := data[part]; exists { if _, isString := value.(string); isString { return true } } } return false } // fallbackToCustomExpr 回退到自定义表达式系统 func (bridge *ExprBridge) fallbackToCustomExpr(expression string, data map[string]interface{}) (interface{}, error) { // 尝试处理字符串拼接表达式 result, err := bridge.evaluateStringConcatenation(expression, data) if err == nil { return result, nil } // 如果不是字符串拼接,尝试简单的数值表达式 numResult, err := bridge.evaluateSimpleNumericExpression(expression, data) if err == nil { return numResult, nil } return nil, fmt.Errorf("unable to evaluate expression: %s, string concat error: %v, numeric error: %v", expression, err, err) } // evaluateStringConcatenation 处理字符串拼接表达式 func (bridge *ExprBridge) evaluateStringConcatenation(expression string, data map[string]interface{}) (interface{}, error) { // 检查是否是字符串拼接表达式 (包含 + 和字符串字面量) if !strings.Contains(expression, "+") { return nil, fmt.Errorf("not a concatenation expression") } // 简单的字符串拼接解析器 // 支持格式: field1 + 'literal' + field2 或 field1 + "_" + field2 parts := strings.Split(expression, "+") var result strings.Builder for _, part := range parts { part = strings.TrimSpace(part) // 处理字符串字面量 (用单引号包围) if strings.HasPrefix(part, "'") && strings.HasSuffix(part, "'") { literal := strings.Trim(part, "'") result.WriteString(literal) } else if strings.HasPrefix(part, "\"") && strings.HasSuffix(part, "\"") { literal := strings.Trim(part, "\"") result.WriteString(literal) } else if part == "_" { // 处理下划线字面量 result.WriteString("_") } else { // 处理字段引用 if value, exists := data[part]; exists { strValue := cast.ToString(value) result.WriteString(strValue) } else { return nil, fmt.Errorf("field %s not found in data", part) } } } return result.String(), nil } // evaluateSimpleNumericExpression 处理简单的数值表达式 func (bridge *ExprBridge) evaluateSimpleNumericExpression(expression string, data map[string]interface{}) (interface{}, error) { expression = strings.TrimSpace(expression) // 处理简单的字段引用 if value, exists := data[expression]; exists { return value, nil } // 处理数字字面量 if num, err := strconv.ParseFloat(expression, 64); err == nil { return num, nil } // 处理简单的数学运算 (例如: field * 2, field + 5) for _, op := range []string{"+", "-", "*", "/"} { if strings.Contains(expression, op) { parts := strings.Split(expression, op) if len(parts) == 2 { left := strings.TrimSpace(parts[0]) right := strings.TrimSpace(parts[1]) // 获取左值 var leftVal float64 if val, exists := data[left]; exists { if f, err := bridge.toFloat64(val); err == nil { leftVal = f } else { return nil, fmt.Errorf("cannot convert left operand to number: %v", val) } } else if f, err := strconv.ParseFloat(left, 64); err == nil { leftVal = f } else { continue // 尝试下一个操作符 } // 获取右值 var rightVal float64 if val, exists := data[right]; exists { if f, err := bridge.toFloat64(val); err == nil { rightVal = f } else { return nil, fmt.Errorf("cannot convert right operand to number: %v", val) } } else if f, err := strconv.ParseFloat(right, 64); err == nil { rightVal = f } else { continue // 尝试下一个操作符 } // 执行运算 switch op { case "+": return leftVal + rightVal, nil case "-": return leftVal - rightVal, nil case "*": return leftVal * rightVal, nil case "/": if rightVal == 0 { return nil, fmt.Errorf("division by zero") } return leftVal / rightVal, nil } } } } return nil, fmt.Errorf("unsupported expression: %s", expression) } // ContainsLikeOperator 检查表达式是否包含LIKE操作符 func (bridge *ExprBridge) ContainsLikeOperator(expression string) bool { // 简单检查是否包含LIKE关键字 upperExpr := strings.ToUpper(expression) return strings.Contains(upperExpr, " LIKE ") } // ContainsIsNullOperator 检查表达式是否包含IS NULL或IS NOT NULL操作符 func (bridge *ExprBridge) ContainsIsNullOperator(expression string) bool { upperExpr := strings.ToUpper(expression) return strings.Contains(upperExpr, " IS NULL") || strings.Contains(upperExpr, " IS NOT NULL") } // isFunctionCall 检查表达式是否是函数调用 func (bridge *ExprBridge) isFunctionCall(expression string) bool { // 如果是CASE表达式,则不是函数调用 trimmed := strings.TrimSpace(expression) upperTrimmed := strings.ToUpper(trimmed) if strings.HasPrefix(upperTrimmed, "CASE ") || strings.HasPrefix(upperTrimmed, "CASE\t") || strings.HasPrefix(upperTrimmed, "CASE\n") { return false } // 检查是否符合简单函数调用模式: function_name(args) // 函数调用应该以标识符开始,后跟括号 if !strings.Contains(expression, "(") || !strings.Contains(expression, ")") { return false } // 检查是否以标识符开始(函数名) for i, r := range trimmed { if i == 0 { if !((r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || r == '_') { return false } } else if r == '(' { // 找到了开括号,说明这可能是函数调用 return true } else if !((r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') || (r >= '0' && r <= '9') || r == '_') { // 遇到了非标识符字符且不是开括号,说明不是简单函数调用 return false } } return false } // PreprocessLikeExpression 预处理LIKE表达式,转换为expr-lang可理解的函数调用 func (bridge *ExprBridge) PreprocessLikeExpression(expression string) (string, error) { // 使用正则表达式匹配LIKE模式 // 匹配: field LIKE 'pattern' 或 `field` LIKE 'pattern' (允许空模式) // 支持反引号标识符和普通标识符 likePattern := `((?:` + "`" + `[^` + "`" + `]+` + "`" + `|\w+)(?:\.(?:` + "`" + `[^` + "`" + `]+` + "`" + `|\w+))*)\s+LIKE\s+'([^']*)'` re, err := regexp.Compile(likePattern) if err != nil { return expression, err } // 替换所有LIKE表达式 result := re.ReplaceAllStringFunc(expression, func(match string) string { submatches := re.FindStringSubmatch(match) if len(submatches) != 3 { return match // 保持原样 } field := submatches[1] pattern := submatches[2] // 处理反引号标识符,去除反引号 if len(field) >= 2 && field[0] == '`' && field[len(field)-1] == '`' { field = field[1 : len(field)-1] // 去掉反引号 } // 将LIKE模式转换为相应的函数调用 return bridge.convertLikeToFunction(field, pattern) }) return result, nil } // PreprocessIsNullExpression 预处理IS NULL和IS NOT NULL表达式,转换为expr-lang可理解的表达式 func (bridge *ExprBridge) PreprocessIsNullExpression(expression string) (string, error) { // 匹配复杂表达式的 IS NOT NULL 模式 (如函数调用) complexNotNullPattern := `([A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\))\s+IS\s+NOT\s+NULL` reComplexNotNull, err := regexp.Compile(complexNotNullPattern) if err != nil { return expression, err } // 先处理复杂表达式的IS NOT NULL result := reComplexNotNull.ReplaceAllString(expression, "is_not_null($1)") // 匹配复杂表达式的 IS NULL 模式 complexNullPattern := `([A-Za-z_][A-Za-z0-9_]*\s*\([^)]*\))\s+IS\s+NULL` reComplexNull, err := regexp.Compile(complexNullPattern) if err != nil { return result, err } // 处理复杂表达式的IS NULL result = reComplexNull.ReplaceAllString(result, "is_null($1)") // 匹配简单字段的 IS NOT NULL 模式 (必须在复杂表达式之后处理) isNotNullPattern := `(\w+(?:\.\w+)*)\s+IS\s+NOT\s+NULL` reNotNull, err := regexp.Compile(isNotNullPattern) if err != nil { return result, err } // 替换简单字段的IS NOT NULL result = reNotNull.ReplaceAllString(result, "$1 != nil") // 匹配简单字段的 IS NULL 模式 isNullPattern := `(\w+(?:\.\w+)*)\s+IS\s+NULL` reNull, err := regexp.Compile(isNullPattern) if err != nil { return result, err } // 再替换简单字段的IS NULL result = reNull.ReplaceAllString(result, "$1 == nil") return result, nil } // ContainsBacktickIdentifiers 检查表达式是否包含反引号标识符 func (bridge *ExprBridge) ContainsBacktickIdentifiers(expression string) bool { return strings.Contains(expression, "`") } // PreprocessBacktickIdentifiers 预处理反引号标识符,去除反引号 func (bridge *ExprBridge) PreprocessBacktickIdentifiers(expression string) (string, error) { // 使用正则表达式匹配反引号标识符 // 匹配: `identifier` 或 `nested.field` backtickPattern := "`([^`]+)`" re, err := regexp.Compile(backtickPattern) if err != nil { return expression, err } // 替换所有反引号标识符,去除反引号 result := re.ReplaceAllString(expression, "$1") return result, nil } // convertLikeToFunction 将LIKE模式转换为expr-lang操作符 func (bridge *ExprBridge) convertLikeToFunction(field, pattern string) string { // 处理空模式 if pattern == "" { return fmt.Sprintf("%s == ''", field) } // 分析模式类型 if strings.HasPrefix(pattern, "%") && strings.HasSuffix(pattern, "%") && len(pattern) > 1 { // %pattern% -> contains操作符(但不是单独的%) inner := strings.Trim(pattern, "%") if inner == "" { // %% 表示匹配任何字符串 return "true" } return fmt.Sprintf("%s contains '%s'", field, inner) } else if strings.HasPrefix(pattern, "%") && len(pattern) > 1 { // %pattern -> endsWith操作符 suffix := strings.TrimPrefix(pattern, "%") return fmt.Sprintf("%s endsWith '%s'", field, suffix) } else if strings.HasSuffix(pattern, "%") && len(pattern) > 1 { // pattern% -> startsWith操作符 prefix := strings.TrimSuffix(pattern, "%") return fmt.Sprintf("%s startsWith '%s'", field, prefix) } else if pattern == "%" { // 单独的%匹配任何字符串 return "true" } else if strings.Contains(pattern, "%") || strings.Contains(pattern, "_") { // 复杂模式(如prefix%suffix)或包含单字符通配符,使用自定义的like_match函数 return fmt.Sprintf("like_match(%s, '%s')", field, pattern) } else { // 精确匹配 return fmt.Sprintf("%s == '%s'", field, pattern) } } // matchesLikePattern 实现LIKE模式匹配 // 支持%(匹配任意字符序列)和_(匹配单个字符) func (bridge *ExprBridge) matchesLikePattern(text, pattern string) bool { return bridge.likeMatch(text, pattern, 0, 0) } // likeMatch 递归实现LIKE匹配算法 func (bridge *ExprBridge) likeMatch(text, pattern string, textIndex, patternIndex int) bool { // 如果模式已经匹配完成 if patternIndex >= len(pattern) { return textIndex >= len(text) // 文本也应该匹配完成 } // 如果文本已经结束,但模式还有非%字符,则不匹配 if textIndex >= len(text) { // 检查剩余的模式是否都是% for i := patternIndex; i < len(pattern); i++ { if pattern[i] != '%' { return false } } return true } // 处理当前模式字符 patternChar := pattern[patternIndex] if patternChar == '%' { // %可以匹配0个或多个字符 // 尝试匹配0个字符(跳过%) if bridge.likeMatch(text, pattern, textIndex, patternIndex+1) { return true } // 尝试匹配1个或多个字符 for i := textIndex; i < len(text); i++ { if bridge.likeMatch(text, pattern, i+1, patternIndex+1) { return true } } return false } else if patternChar == '_' { // _匹配恰好一个字符 return bridge.likeMatch(text, pattern, textIndex+1, patternIndex+1) } else { // 普通字符必须精确匹配 if text[textIndex] == patternChar { return bridge.likeMatch(text, pattern, textIndex+1, patternIndex+1) } return false } } // toFloat64 将值转换为float64 func (bridge *ExprBridge) toFloat64(val interface{}) (float64, error) { switch v := val.(type) { case float64: return v, nil case float32: return float64(v), nil case int: return float64(v), nil case int32: return float64(v), nil case int64: return float64(v), nil case string: return strconv.ParseFloat(v, 64) default: return 0, fmt.Errorf("cannot convert %T to float64", val) } } // GetFunctionInfo 获取函数信息,统一两个系统的函数 func (bridge *ExprBridge) GetFunctionInfo() map[string]interface{} { bridge.mutex.RLock() defer bridge.mutex.RUnlock() info := make(map[string]interface{}) // StreamSQL函数信息 - 动态获取所有当前注册的函数 streamSQLFuncs := make(map[string]interface{}) allFunctions := ListAll() // 动态获取所有注册的函数 for name, fn := range allFunctions { streamSQLFuncs[name] = map[string]interface{}{ "name": fn.GetName(), "type": fn.GetType(), "category": fn.GetCategory(), "description": fn.GetDescription(), "source": "StreamSQL", } } info["streamsql"] = streamSQLFuncs // expr-lang/expr内置函数(列出主要的) exprBuiltins := map[string]interface{}{ // 数学函数 "abs": map[string]interface{}{"category": "math", "description": "absolute value", "source": "expr-lang"}, "ceil": map[string]interface{}{"category": "math", "description": "ceiling", "source": "expr-lang"}, "floor": map[string]interface{}{"category": "math", "description": "floor", "source": "expr-lang"}, "round": map[string]interface{}{"category": "math", "description": "round", "source": "expr-lang"}, "max": map[string]interface{}{"category": "math", "description": "maximum", "source": "expr-lang"}, "min": map[string]interface{}{"category": "math", "description": "minimum", "source": "expr-lang"}, // 字符串函数 "trim": map[string]interface{}{"category": "string", "description": "trim whitespace", "source": "expr-lang"}, "upper": map[string]interface{}{"category": "string", "description": "to uppercase", "source": "expr-lang"}, "lower": map[string]interface{}{"category": "string", "description": "to lowercase", "source": "expr-lang"}, "split": map[string]interface{}{"category": "string", "description": "split string", "source": "expr-lang"}, "replace": map[string]interface{}{"category": "string", "description": "replace substring", "source": "expr-lang"}, "indexOf": map[string]interface{}{"category": "string", "description": "find index", "source": "expr-lang"}, "hasPrefix": map[string]interface{}{"category": "string", "description": "check prefix", "source": "expr-lang"}, "hasSuffix": map[string]interface{}{"category": "string", "description": "check suffix", "source": "expr-lang"}, // 数组/集合函数 "all": map[string]interface{}{"category": "array", "description": "all elements satisfy", "source": "expr-lang"}, "any": map[string]interface{}{"category": "array", "description": "any element satisfies", "source": "expr-lang"}, "filter": map[string]interface{}{"category": "array", "description": "filter elements", "source": "expr-lang"}, "map": map[string]interface{}{"category": "array", "description": "transform elements", "source": "expr-lang"}, "find": map[string]interface{}{"category": "array", "description": "find element", "source": "expr-lang"}, "count": map[string]interface{}{"category": "array", "description": "count elements", "source": "expr-lang"}, "concat": map[string]interface{}{"category": "array", "description": "concatenate arrays", "source": "expr-lang"}, "flatten": map[string]interface{}{"category": "array", "description": "flatten array", "source": "expr-lang"}, // 时间函数 "now": map[string]interface{}{"category": "datetime", "description": "current time", "source": "expr-lang"}, "duration": map[string]interface{}{"category": "datetime", "description": "parse duration", "source": "expr-lang"}, "date": map[string]interface{}{"category": "datetime", "description": "parse date", "source": "expr-lang"}, // 类型转换 "int": map[string]interface{}{"category": "conversion", "description": "to integer", "source": "expr-lang"}, "float": map[string]interface{}{"category": "conversion", "description": "to float", "source": "expr-lang"}, "string": map[string]interface{}{"category": "conversion", "description": "to string", "source": "expr-lang"}, "type": map[string]interface{}{"category": "conversion", "description": "get type", "source": "expr-lang"}, // JSON处理 "toJSON": map[string]interface{}{"category": "json", "description": "to JSON", "source": "expr-lang"}, "fromJSON": map[string]interface{}{"category": "json", "description": "from JSON", "source": "expr-lang"}, // Base64编码 "toBase64": map[string]interface{}{"category": "encoding", "description": "to Base64", "source": "expr-lang"}, "fromBase64": map[string]interface{}{"category": "encoding", "description": "from Base64", "source": "expr-lang"}, } info["expr-lang"] = exprBuiltins return info } // ResolveFunction 解析函数调用,优先使用StreamSQL函数 func (bridge *ExprBridge) ResolveFunction(name string) (interface{}, bool, string) { bridge.mutex.RLock() defer bridge.mutex.RUnlock() // 进行大小写不敏感的查找 lowerName := strings.ToLower(name) // 首先检查StreamSQL函数(优先级更高) - 动态获取 allFunctions := ListAll() if fn, exists := allFunctions[lowerName]; exists { return fn, true, "streamsql" } // 然后检查是否是expr-lang内置函数 exprBuiltins := []string{ "abs", "ceil", "floor", "round", "max", "min", // math "trim", "upper", "lower", "split", "replace", "indexOf", "hasPrefix", "hasSuffix", // string "all", "any", "filter", "map", "find", "count", "flatten", // array (移除concat) "now", "duration", "date", // time "int", "float", "string", "type", // conversion "toJSON", "fromJSON", "toBase64", "fromBase64", // encoding "len", "get", // misc } for _, builtin := range exprBuiltins { if strings.ToLower(builtin) == lowerName { return nil, true, "expr-lang" // expr-lang会自动处理 } } return nil, false, "" } // IsExprLangFunction 检查函数名是否是expr-lang内置函数 func (bridge *ExprBridge) IsExprLangFunction(name string) bool { // expr-lang内置函数列表(移除concat避免冲突) exprBuiltins := []string{ "abs", "ceil", "floor", "round", "max", "min", // math "trim", "upper", "lower", "split", "replace", "indexOf", "hasPrefix", "hasSuffix", // string "all", "any", "filter", "map", "find", "count", "flatten", // array (移除concat) "now", "duration", "date", // time "int", "float", "string", "type", // conversion "toJSON", "fromJSON", "toBase64", "fromBase64", // encoding "len", "get", // misc } for _, builtin := range exprBuiltins { if builtin == name { return true } } return false } // 全局桥接器实例 var globalBridge *ExprBridge var globalBridgeMutex sync.RWMutex // GetExprBridge 获取全局桥接器实例 func GetExprBridge() *ExprBridge { // 首先使用读锁检查是否已初始化 globalBridgeMutex.RLock() if globalBridge != nil { defer globalBridgeMutex.RUnlock() return globalBridge } globalBridgeMutex.RUnlock() // 使用写锁进行初始化 globalBridgeMutex.Lock() defer globalBridgeMutex.Unlock() // 双重检查模式,防止并发初始化 if globalBridge == nil { globalBridge = NewExprBridge() } return globalBridge } // 便捷函数:直接评估表达式 func EvaluateWithBridge(expression string, data map[string]interface{}) (interface{}, error) { return GetExprBridge().EvaluateExpression(expression, data) } // 便捷函数:获取所有可用函数信息 func GetAllAvailableFunctions() map[string]interface{} { return GetExprBridge().GetFunctionInfo() }