使用指针时的延迟执行(defer)

huangapple go评论80阅读模式
英文:

Using defer with pointers

问题

让我们假设我有以下代码:

func getConnection(fileName string) *os.File {
    file, err := os.Open(fileName)
    // 检查错误
    return file
}

我使用这个函数来打开一个文件,并且这个函数是从另一个执行其他操作的函数中调用的。

我的问题是,既然我已经打开了文件,如何关闭它呢?如果我在getConnection()函数内部添加defer file.Close(),那么它不会在返回之前关闭文件吗?在调用函数中使用defer是否有意义呢?

英文:

Let us say that I have the following code:

func getConnection(fileName string) *os.File {
    file, err := os.Open(fileName)
    //Check for error
    return file
}

I use this function to open a file and the function is called from another function that does some other activity.

My question is, now that I have opened the file, how do I close it. If I were to add defer file.Close() inside getConnection(), wouldn't it close the file before returning? Does it make sense to use defer inside the calling function?

答案1

得分: 9

如果你的函数的目的是返回一个文件,为什么要在返回文件的函数中关闭它呢?

在这种情况下,正确关闭文件的责任应该由调用者来承担,最好使用defer关键字:

func usingGetConnection() {
    f := getConnection("file.txt")
    defer f.Close()
    // 在这里使用 f
}

虽然你的getConnection()函数忽略了错误,但你应该使用多返回值来指示此类问题:

func getConnection(fileName string) (*os.File, error) {
    file, err := os.Open(fileName)
    // 检查错误
    if err != nil {
        return nil, err
    }
    return file, nil
}

并在使用它时:

func usingGetConnection() {
    f, err := getConnection("file.txt")
    if err != nil {
        panic(err) // 根据需要处理错误
    }
    defer f.Close()
    // 在这里使用 f
}
英文:

If the purpose of your function is to return a file, why would you want to close it in the function that returns it?

In this case it is the responsibility of the caller to properly close the file, preferably with defer:

func usingGetConnection() {
    f := getConnection("file.txt")
    defer f.Close()
    // Use f here
}

Although your getConnection() function swallows errors, you should use multi-return value to indicate problems like this:

func getConnection(fileName string) (*os.File, error) {
    file, err := os.Open(fileName)
    //Check for error
    if err != nil {
        return nil, err
    }
    return file, nil
}

And using it:

func usingGetConnection() {
    f, err := getConnection("file.txt")
    if err != nil {
        panic(err) // Handle err somehow
    }
    defer f.Close()
    // Use f here
}

huangapple
  • 本文由 发表于 2015年2月2日 21:45:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/28279155.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定