首页 > 解决方案 > 理解 Go 的 exec.Output() 函数

问题描述

我正在阅读Go模块(https://golang.org/pkg/os/exec/#Cmd.OutputOutput() )中类型方法的源代码:Cmdexec

// Output runs the command and returns its standard output.
// Any returned error will usually be of type *ExitError.
// If c.Stderr was nil, Output populates ExitError.Stderr.
func (c *Cmd) Output() ([]byte, error) {
    if c.Stdout != nil {
        return nil, errors.New("exec: Stdout already set")
    }
    var stdout bytes.Buffer
    c.Stdout = &stdout

    captureErr := c.Stderr == nil
    if captureErr {
        c.Stderr = &prefixSuffixSaver{N: 32 << 10}
    }

    err := c.Run()
    if err != nil && captureErr {
        if ee, ok := err.(*ExitError); ok {
            ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
        }
    }
    return stdout.Bytes(), err
}

我很难理解这部分:

    if ee, ok := err.(*ExitError); ok {
        ee.Stderr = c.Stderr.(*prefixSuffixSaver).Bytes()
    }

据我了解,ee指针将不再位于if块末尾的范围内,并且由于块的主体if只是设置Stderr此实例的字段,因此唯一有用的方法是通过副作用(例如实际上写了美化的错误)。不过,我并没有立即理解这是如何发生的。

这段代码本质上是做什么的?

标签: go

解决方案


if ee, ok := err.(*ExitError); ok {

如果err是 类型*ExitError,那么ee将是指向存储在中的 ExitError 的指针err。因此,即使ee将超出范围,*ExitError仍将存在,由 指向err,并且对其所做的任何更改都将保留。


推荐阅读