开放的编程资料库

当前位置:我爱分享网 > Go教程 > 正文

Golang中使用defer语句

Godefer教程展示了如何在Golang中使用defer语句延迟执行。

defer语句推迟函数的执行,直到周围的函数返回。立即评估延迟调用的参数。

defer语句将defer关键字之后的函数调用添加到堆栈中。由于调用放在堆栈上,因此称为后进先出(LIFO)顺序。

defer语句的一个常见用途是清理资源,例如打开的文件、网络连接或数据库句柄。

$ go version
go version go1.18.1 linux/amd64

我们使用Go版本1.18。

去延迟语句

下面是Go的defer语句的简单演示。

package main

import "fmt"

func main() {

    defer fmt.Println("sky")
    fmt.Println("falcon")
}

我们有两个Println函数调用。第一个用defer关键字延迟。

$ go run simple.go 
falcon
sky

去延迟参数评估

延迟函数的参数会立即求值。

package main

import "fmt"

func main() {

    fmt.Println("start")
    for i := 1; i <= 5; i++ {
        defer fmt.Println(i)
    }
    fmt.Println("end")
}

defer语句放在for循环内。i变量在循环执行期间被评估。

$ go run arg_eval.go 
start
end
5
4
3
2
1

去延迟函数调用顺序

延迟的函数调用放在堆栈上,并以后进先出(LIFO)的顺序调用。

package main

import "fmt"

func main() {

    defer fmt.Println("one")
    defer fmt.Println("two")
    defer fmt.Println("three")
    defer fmt.Println("four")

    defer fmt.Println("4")
    defer fmt.Println("3")
    defer fmt.Println("2")
    defer fmt.Println("1")
}

deferfmt.Println("one")先延迟,最后执行。deferfmt.Println("1")最后延迟并首先执行。

$ go run defer_order.go 
1
2
3
4
four
three
two
one

去延迟资源释放

defer语句常用于释放必要的资源,如打开的文件。

sky
cloud
cup
wood
rock
sea
tree
oil
book
falcon

这是words.txt文件。

package main

import (
    "bufio"
    "fmt"
    "log"
    "os"
)

func main() {

    f, err := os.Open("words.txt")

    if err != nil {
        log.Fatal(err)
    }

    defer f.Close()

    scanner := bufio.NewScanner(f)

    for scanner.Scan() {

        fmt.Println(scanner.Text())
    }

    if err := scanner.Err(); err != nil {
        log.Fatal(err)
    }
}

在代码示例中,我们逐行读取打开的文件。

f, err := os.Open("words.txt")

if err != nil {
    log.Fatal(err)
}

defer f.Close()

打开words.txt文件并检查错误后,我们延迟Close方法。它在main函数结束时释放打开的文件。

恐慌地推迟

延迟的函数调用即使在函数崩溃时也会执行。

package main

import "fmt"

func main() {
    defer fmt.Println("sky")
    panic("terminating")
    fmt.Println("falcon")
}

该示例在延迟Println函数后调用panic;尽管如此,它还是被执行了。

$ go run defpanic.go 
sky
panic: terminating

goroutine 1 [running]:
main.main()
	/home/janbodnar/Documents/prog/golang/defer/defpanic/defpanic.go:7 +0xb9
exit status 2

在本教程中,我们介绍了Golang中的defer语句。

列出所有Go教程。

未经允许不得转载:我爱分享网 » Golang中使用defer语句

感觉很棒!可以赞赏支持我哟~

赞(0) 打赏