在golang中,如何将字符串内容转换为golang代码来执行呢?

遇到一个问题,需要输入自定义代码,然后将这段输入的字符串转换为代码来执行。

比如我有如下代码:

code := `math.floor(1234)`
result := .....

我要如何将code这个字符串的内容转换为结果,并赋值到result这个变量中呢?
在PHP中有eval函数可以使用,在golang要如何实现?

共 7 个回复


yufeng

golang 不是php

# 0

heimeil

package main

import (
    "bufio"
    "errors"
    "fmt"
    "os"
    "os/exec"
    "runtime"
)

var (
    dirSeparator string = "/"
    tempDir      string
)

func init() {
    if runtime.GOOS == "windows" {
        dirSeparator = "\\"
    }
    tempDir = os.TempDir() + dirSeparator + "goeval"
    os.Mkdir(tempDir, os.ModePerm)
}

func main() {
    result, err := eval(`println(math.Floor(1234))`, "math")
    if err != nil {
        fmt.Println("error:", err)
    }
    fmt.Println(result)
}

func eval(code string, imports ...string) (result string, err error) {
    tmpfile, err := os.Create(tempDir + dirSeparator + "temp.go")
    if err != nil {
        return "", err
    }
    w := bufio.NewWriter(tmpfile)
    w.WriteString("package main\r\n")
    w.WriteString("\r\n")
    if len(imports) > 0 {
        tmpArgs := []string{"get"}
        tmpArgs = append(tmpArgs, imports...)
        goget := exec.Command("go", tmpArgs...)
        _, err = goget.Output()
        if err != nil {
            return "", err
        }
        w.WriteString("import (\r\n")
        for _, v := range imports {
            w.WriteString("\t" + `"` + v + `"` + "\r\n")
        }
        w.WriteString(")\r\n")
        w.WriteString("\r\n")
    }
    w.WriteString("func main() {\r\n")
    w.WriteString("\t" + code + "\r\n")
    w.WriteString("}\r\n")
    w.Flush()
    tmpfile.Close()
    cmd := exec.Command("go", "run", tmpfile.Name())
    res, err := cmd.CombinedOutput()
    if err != nil {
        return "", errors.New(string(res) + err.Error())
    }
    os.Remove(tmpfile.Name())
    return string(res), nil
}
# 1

qkevin123

这,曲线救国,,,,,,

# 2

jimmykuu

用户输入个 rm / 就呵呵了。

# 3

heimeil

@jimmykuu
专门建个用户,权限控死应该可以吧

# 5

wjvlangz

你需要一个golang的虚拟机。

# 6