返回

Go defer的一些神奇规则,你了解吗?

后端

在Go语言中,defer是一个非常有用的,它允许你推迟一个函数的调用或变量的操作,直到当前函数返回之后再执行。但是,在使用defer时,有一些规则需要注意,如果不了解这些规则,代码实现的最终结果可能会与你预期的不一致。

1. defer的作用范围仅限于当前函数

defer只能推迟当前函数中的函数调用或变量的操作,而不能推迟其他函数中的函数调用或变量的操作。例如,以下代码是错误的:

package main

import "fmt"

func main() {
    defer fmt.Println("Hello, world!")
}

func otherFunc() {
    defer fmt.Println("Hello, other world!")
}

在上面的代码中,defer fmt.Println("Hello, other world!")位于otherFunc函数中,但是defer只能推迟当前函数中的函数调用或变量的操作,因此这句话是无效的。

2. defer函数执行的顺序与定义的顺序相反

defer函数的执行顺序与定义的顺序相反,也就是说,defer函数越早定义,执行得越晚。例如,以下代码将输出"world",然后输出"hello":

package main

import "fmt"

func main() {
    defer fmt.Println("hello")
    defer fmt.Println("world")
}

3. defer的返回值会被忽略

defer函数的返回值会被忽略,因此,如果一个defer函数有返回值,那么这个返回值将不会被使用。例如,以下代码不会输出任何东西:

package main

import "fmt"

func main() {
    defer fmt.Println("hello")
    return
}

4. defer函数可以用来释放资源

defer函数可以用来释放资源,例如,你可以使用defer来关闭文件或网络连接。例如,以下代码将打开一个文件,然后在函数返回时自动关闭这个文件:

package main

import (
    "fmt"
    "io"
    "os"
)

func main() {
    file, err := os.Open("file.txt")
    if err != nil {
        fmt.Println(err)
        return
    }
    defer file.Close()

    // Do something with the file

    return
}

5. defer函数可以用来实现后置函数

defer函数可以用来实现后置函数,后置函数是指在函数返回之后执行的函数。例如,以下代码将创建一个后置函数,这个后置函数将在main函数返回之后执行:

package main

import "fmt"

func main() {
    defer func() {
        fmt.Println("This is a post-function.")
    }()

    // Do something

    return
}

通过掌握这些规则,你可以更熟练地使用defer来编写出更加健壮、高效的代码。