package runner import ( "bytes" "context" "io/ioutil" "os" "os/exec" "path/filepath" "time" "github.com/google/uuid" ) type GoRunner struct { TempDir string } func (r *GoRunner) Run(ctx context.Context, code string) (*ExecutionResult, error) { // 创建唯一的工作目录 workDir := filepath.Join(r.TempDir, uuid.New().String()) if err := os.MkdirAll(workDir, 0755); err != nil { return nil, err } defer os.RemoveAll(workDir) // 清理 // 写入main.go // 注意:这里假设代码是一个完整的package main // 如果用户只提供了函数片段,可能需要包装。这里假设是完整代码。 filePath := filepath.Join(workDir, "main.go") if err := ioutil.WriteFile(filePath, []byte(code), 0644); err != nil { return nil, err } // 准备命令 // 使用 go run 运行 cmd := exec.CommandContext(ctx, "go", "run", "main.go") cmd.Dir = workDir // 捕获输出 var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr startTime := time.Now() err := cmd.Run() duration := time.Since(startTime).Milliseconds() result := &ExecutionResult{ Output: stdout.String(), Error: stderr.String(), Duration: duration, } if err != nil { if exitErr, ok := err.(*exec.ExitError); ok { result.ExitCode = exitErr.ExitCode() } else { result.ExitCode = -1 } // 如果是超时 if ctx.Err() == context.DeadlineExceeded { result.Error += "\nExecution timed out" } } return result, nil }