package main import ( "fmt" "strings" "github.com/traefik/yaegi/interp" "github.com/traefik/yaegi/stdlib" ) func main() { calculateSimple("(2+3)*5") calculateSimple("15/5") // 测试多行代码(使用专门的多行函数) code := `x := 10 if x > 5 { return "大于5" } else { return "小于等于5" }` calculateMultiLine(code) // // 获取配置实例 // cfg := config.GetConfig() // // 使用配置 // if cfg.IsDatabaseConfigured() { // dbConfig := cfg.GetDatabaseConfig() // fmt.Printf("Host: %s\n", dbConfig.Host) // fmt.Printf("Port: %d\n", dbConfig.Port) // fmt.Printf("Database: %s\n", dbConfig.Database) // } // //authConfig := cfg.GetAuth() // //fmt.Printf("token: %s\n", authConfig.Token) // serviceConfig := cfg.GetServiceConfig() // fmt.Printf("ReadTimeout: %d秒\n", serviceConfig.ReadTimeout) // fmt.Printf("WriteTimeout: %d秒\n", serviceConfig.WriteTimeout) // fmt.Printf("IdleTimeout: %d秒\n", serviceConfig.IdleTimeout) } func calculateSimple(expression string) (string, error) { i := interp.New(interp.Options{}) i.Use(stdlib.Symbols) // 包装成匿名函数立即调用,既简洁又安全 code := fmt.Sprintf("(func() interface{} { return %s })()", expression) v, err := i.Eval(code) if err != nil { fmt.Printf("calculateSimple: err v:%v \n", err) return "", err } fmt.Printf("calculateSimple: %s v:%v \n", expression, v) return fmt.Sprintf("%v", v), nil } // 专门处理多行代码(if/for/变量声明等) func calculateMultiLine(code string) (string, error) { i := interp.New(interp.Options{}) i.Use(stdlib.Symbols) // 关键:整个代码块作为函数体,最后一行作为返回值 wrappedCode := fmt.Sprintf(` (func() interface{} { %s })()`, code) v, err := i.Eval(wrappedCode) if err != nil { fmt.Printf("calculateMultiLine 错误: %v\n代码: %s\n", err, code) return "", err } fmt.Printf("calculateMultiLine 成功: %v\n", v) return fmt.Sprintf("%v", v), nil } // 更智能的版本:自动判断使用哪种处理方式 func calculateAuto(expression string) (string, error) { // 如果是纯数学表达式(只有数字和运算符) if isPureMath(expression) { return calculateSimple(expression) } // 否则当做多行代码处理 return calculateMultiLine(expression) } func isPureMath(expr string) bool { // 移除非空格的空白字符 cleaned := strings.ReplaceAll(expr, "\n", "") cleaned = strings.ReplaceAll(cleaned, "\t", "") cleaned = strings.ReplaceAll(cleaned, " ", "") // 检查是否只包含数字、运算符、括号和小数点 for _, ch := range cleaned { if !((ch >= '0' && ch <= '9') || ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '(' || ch == ')' || ch == '.') { return false } } return len(cleaned) > 0 }