📜  使用 defer 关键字的 Golang 程序

📅  最后修改于: 2021-10-24 14:23:34             🧑  作者: Mango

go 中defer关键字的主要用途是用来清理打开的文件、网络连接、数据库句柄等使用的资源。 通过保持关闭函数/文件的调用更近,这有助于减少出错的机会调用打开语句。后面紧跟 defer 关键字的语句被放入堆栈,最后按照后进先出 (LIFO) 顺序调用它们。

例子:

package main
  
import "fmt"
  
func main() {
    defer fmt.Println("First")
    defer fmt.Println("Second")
    fmt.Println("Last")
}

输出:

Last
Second
First

在这里,您可以看到报表是根据 LIFO 打印的。但是,这不是 defer 的目的,所以我们将查看一个程序来了解 defer 关键字的主要用途。

例子:

func write(fileName string, text string) error {
    file, err := os.Create(fileName)
    if err != nil {
        return err
    }
    _, err = io.WriteString(file, text)
    if err != nil {
        return err
    }
    file.Close()
    return nil
}

在这种情况下,如果函数io.WriteString失败,则程序将返回错误“err”并且无法关闭文件,这将导致资源浪费,因此这里 defer 将很有用。

func write(fileName string, text string) error {
    file, err := os.Create(fileName)
    if err != nil {
        return err
    }

 // This statement will surely run at the end no 
 // matter what the program goes through.
  defer file.Close()
 
    _, err = io.WriteString(file, text)
    if err != nil {
        return err
    }

    return file.Close()
}

在这个程序中,语句 defer file.Close()将在函数的末尾运行,如果程序中有错误,那么它将能够关闭程序中先前打开的文件,从而保存资源。以下是相同的完整程序。

package main
  
import (
    "io"
    "log"
    "os"
)
  
func main() {
    if err := write("readme.txt", "This is a readme file"); err != nil {
        log.Fatal("failed to write file:", err)
          
    }
}
  
func write(fileName string, text string) error {
    file, err := os.Create(fileName)
    if err != nil {
        return err
    }
    defer file.Close()
    _, err = io.WriteString(file, text)
    if err != nil {
        return err
    }
  
    return file.Close()
}