gpt4 book ai didi

go - 如何理解defer语句

转载 作者:IT王子 更新时间:2023-10-29 01:38:31 28 4
gpt4 key购买 nike

我有两个关于golang中defer语句的例子,第一个不正确,第二个正确。但我认为他们有同样的问题,在我看来我认为第二个仍然存在文件描述符用完的风险,任何人都可以帮助我澄清为什么第二个是正确的吗?谢谢!

示例 1:

for _, filename := range filenames {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close() // NOTE: risky; could run out of file descriptors
// ...process f...
}

例子2:

for _, filename := range filenames {
if err := doFile(filename); err != nil {
return err
}
}
func doFile(filename string) error {
f, err := os.Open(filename)
if err != nil {
return err
}
defer f.Close()
// ...process f...
}

最佳答案

延迟函数在封闭函数返回时运行。 Spec: Defer statements:

A "defer" statement invokes a function whose execution is deferred to the moment the surrounding function returns, either because the surrounding function executed a return statement, reached the end of its function body, or because the corresponding goroutine is panicking.

在您的第一个示例中,您使用了一个 for 循环,其中您使用了 defer 语句,但是延迟函数不会在迭代结束时执行,只会在 for 循环之后(当封闭函数结束时)。这意味着您在 for 循环中打开的所有文件都将保持打开状态,直到“结束”。如果 filenames 包含一千个有效文件名,则循环将(尝试)在开始关闭其中任何文件之前打开一千个文件。

在您的第二个示例中,您将文件处理“外包”给了一个单独的函数。在这个函数中使用 defer 是完全不同的,因为当这个函数返回时,延迟函数 (File.Close()) 将首先被调用。因此,在您的第二个示例中,发布的代码始终打开最多 1 个文件,无论 filenames 包含多少元素。

关于go - 如何理解defer语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46521614/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com