Golang中多个defer的使用哪种方式更好

Golang中多个defer的使用哪种方式更好

defer func(){
    A()
    B()
}()

或者

defer B()
defer A()
6 回复

对于可写的文件,你可以使用 defer 来关闭,但务必记得最后调用 Flush() 并检查返回的错误。

更多关于Golang中多个defer的使用哪种方式更好的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


我倾向于在获取资源后尽快使用单个 defer 来释放资源。

我从不使用与资源无关的 defer

因此从我的角度来看,版本1的情况不太可能发生。

我认为使用多个 defer() 函数调用会更好。这样你就有空间在 defer func2() 中处理来自 defer func1() 的失败。

在以下代码中:

defer func(){
A()
B()
}()

你需要处理 A() 和 B() 中的任何错误。

下面的代码具有更大的灵活性,更易于处理且代码可读性更强:

defer B()
defer A()

是的,我本不该提起这件事,而且我刚刚打出来的那个例子确实不好……当然,在可写文件上使用 defer close 是可行的。但同样地,错误处理通常应该做得更好。如果你正在写入文件,但在某个地方失败了,关闭文件并不是首要考虑的问题。我们应该留下一个只写了一半的文件吗?很可能应该以某种方式清理它。如果我们做得正确,我们可能正在写入一个临时文件,打算将其重命名为最终的目标文件名。如果是这样,关闭文件并不是最后要做的事情(重命名才是),我们不应该使用 defer 来关闭它,等等。

就像我说的,这个例子不好,实际情况要复杂得多。 表情

我认为这取决于在上下文中哪种方式更清晰。如果它们是两个独立的事物,分开处理可能更好。

in, err := os.Open(...)
// ...
defer in.Close()

out, err := os.Create(...)
// ...
defer out.Close() // 通常不要在可写文件上延迟关闭。此处仅为示例。

如果只是两个应该一起执行的操作,放在一起也可以。例如,这里设置写入截止时间只是为了确保关闭操作能正常执行:

conn, err := net.DialTLS(...)
// ...
defer func() {
    conn.SetWriteDeadline(time.Now().Add(time.Second))
    conn.Close()
}()

但正如下面提到的(我进行了快速编辑,抱歉:)),这实际上是因为延迟调用仍然针对的是同一个资源。

在Go语言中,多个defer语句的执行顺序是后进先出(LIFO),因此两种方式在行为上有明显差异。第一种方式使用单个defer调用一个匿名函数,其中A()B()按代码顺序执行;第二种方式使用两个独立的defer语句,B()会先于A()执行。

如果希望A()B()按声明顺序执行(即先A()B()),第一种方式更合适,因为它将多个操作封装在一个延迟函数中,确保执行顺序与代码顺序一致。第二种方式会导致逆序执行,即B()先执行,A()后执行。

示例代码说明:

package main

import "fmt"

func A() {
    fmt.Println("Function A")
}

func B() {
    fmt.Println("Function B")
}

func main() {
    // 方式1: 使用单个defer,A()和B()按顺序执行
    defer func() {
        A()
        B()
    }()
    fmt.Println("Main function - way 1")
    // 输出:
    // Main function - way 1
    // Function A
    // Function B

    // 方式2: 使用多个defer,B()先执行,A()后执行
    defer B()
    defer A()
    fmt.Println("Main function - way 2")
    // 输出:
    // Main function - way 2
    // Function A
    // Function B
}

在实际应用中,选择哪种方式取决于需求:如果多个操作需要作为一个整体按顺序延迟执行,使用第一种方式;如果需要独立控制每个延迟操作的执行顺序,使用第二种方式。第一种方式更易于维护顺序逻辑,而第二种方式在需要逆序清理资源时(如关闭文件句柄)更常见。

回到顶部