暫無描述
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. "github.com/traefik/yaegi/interp"
  6. "github.com/traefik/yaegi/stdlib"
  7. )
  8. func main() {
  9. calculateSimple("(2+3)*5")
  10. calculateSimple("15/5")
  11. // 测试多行代码(使用专门的多行函数)
  12. code := `x := 10
  13. if x > 5 {
  14. return "大于5"
  15. } else {
  16. return "小于等于5"
  17. }`
  18. calculateMultiLine(code)
  19. // // 获取配置实例
  20. // cfg := config.GetConfig()
  21. // // 使用配置
  22. // if cfg.IsDatabaseConfigured() {
  23. // dbConfig := cfg.GetDatabaseConfig()
  24. // fmt.Printf("Host: %s\n", dbConfig.Host)
  25. // fmt.Printf("Port: %d\n", dbConfig.Port)
  26. // fmt.Printf("Database: %s\n", dbConfig.Database)
  27. // }
  28. // //authConfig := cfg.GetAuth()
  29. // //fmt.Printf("token: %s\n", authConfig.Token)
  30. // serviceConfig := cfg.GetServiceConfig()
  31. // fmt.Printf("ReadTimeout: %d秒\n", serviceConfig.ReadTimeout)
  32. // fmt.Printf("WriteTimeout: %d秒\n", serviceConfig.WriteTimeout)
  33. // fmt.Printf("IdleTimeout: %d秒\n", serviceConfig.IdleTimeout)
  34. }
  35. func calculateSimple(expression string) (string, error) {
  36. i := interp.New(interp.Options{})
  37. i.Use(stdlib.Symbols)
  38. // 包装成匿名函数立即调用,既简洁又安全
  39. code := fmt.Sprintf("(func() interface{} { return %s })()", expression)
  40. v, err := i.Eval(code)
  41. if err != nil {
  42. fmt.Printf("calculateSimple: err v:%v \n", err)
  43. return "", err
  44. }
  45. fmt.Printf("calculateSimple: %s v:%v \n", expression, v)
  46. return fmt.Sprintf("%v", v), nil
  47. }
  48. // 专门处理多行代码(if/for/变量声明等)
  49. func calculateMultiLine(code string) (string, error) {
  50. i := interp.New(interp.Options{})
  51. i.Use(stdlib.Symbols)
  52. // 关键:整个代码块作为函数体,最后一行作为返回值
  53. wrappedCode := fmt.Sprintf(`
  54. (func() interface{} {
  55. %s
  56. })()`, code)
  57. v, err := i.Eval(wrappedCode)
  58. if err != nil {
  59. fmt.Printf("calculateMultiLine 错误: %v\n代码: %s\n", err, code)
  60. return "", err
  61. }
  62. fmt.Printf("calculateMultiLine 成功: %v\n", v)
  63. return fmt.Sprintf("%v", v), nil
  64. }
  65. // 更智能的版本:自动判断使用哪种处理方式
  66. func calculateAuto(expression string) (string, error) {
  67. // 如果是纯数学表达式(只有数字和运算符)
  68. if isPureMath(expression) {
  69. return calculateSimple(expression)
  70. }
  71. // 否则当做多行代码处理
  72. return calculateMultiLine(expression)
  73. }
  74. func isPureMath(expr string) bool {
  75. // 移除非空格的空白字符
  76. cleaned := strings.ReplaceAll(expr, "\n", "")
  77. cleaned = strings.ReplaceAll(cleaned, "\t", "")
  78. cleaned = strings.ReplaceAll(cleaned, " ", "")
  79. // 检查是否只包含数字、运算符、括号和小数点
  80. for _, ch := range cleaned {
  81. if !((ch >= '0' && ch <= '9') ||
  82. ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
  83. ch == '(' || ch == ')' || ch == '.') {
  84. return false
  85. }
  86. }
  87. return len(cleaned) > 0
  88. }