go - 理解 Go 的 exec.Output() 函数
问题描述
我正在阅读Go模块(https://golang.org/pkg/os/exec/#Cmd.OutputOutput()
)中类型方法的源代码:Cmd
exec
// 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
此实例的字段,因此唯一有用的方法是通过副作用(例如实际上写了美化的错误)。不过,我并没有立即理解这是如何发生的。
这段代码本质上是做什么的?
解决方案
if ee, ok := err.(*ExitError); ok {
如果err
是 类型*ExitError
,那么ee
将是指向存储在中的 ExitError 的指针err
。因此,即使ee
将超出范围,*ExitError
仍将存在,由 指向err
,并且对其所做的任何更改都将保留。
推荐阅读
- postgresql - 如何使用 centos:8 docker image 运行 postgresql 客户端?
- visual-studio-code - 如何使用鼠标后退和前进按钮将导航设置到 Visual Studio Code 中的最后一个或下一个光标位置?
- angular - 如何在调度操作之前检查实体是否存在于商店中?
- javascript - 我可以对不同的连接(非并发)多次使用相同的 WebRTC 对等连接对象吗?
- python - 如何在Python中分组后减去行?
- reactjs - 如何在 next.js 网络应用中实现 OneSignal 网络推送?
- xpath - Xpath(或)条件与其中一个节点
- python - 为什么我的反向传播算法的性能卡住了?
- sql - 如何对匹配项进行分组
- css - 覆盖类会弄乱整个网站