MST
星途 面试题库

面试题:Go中defer语句的执行顺序及场景应用

请简述Go语言中defer语句的执行顺序,并举例说明在哪些场景下会使用到defer语句,例如文件操作场景。
47.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

defer语句的执行顺序

在Go语言中,defer语句会将其后面跟随的函数延迟到包含该defer语句的函数即将返回时才执行。多个defer语句的执行顺序是后进先出(LIFO),即最后定义的defer语句对应的函数最先执行。

举例说明使用场景

  1. 文件操作场景: 在对文件进行读写操作时,打开文件后需要在函数结束时关闭文件,以释放资源。使用defer可以确保无论函数如何返回(正常返回或因错误提前返回),文件都会被关闭。
package main

import (
    "fmt"
    "os"
)

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

    // 在这里进行文件读取操作
    // 函数结束时,无论是否发生错误,都会执行file.Close()
}
  1. 数据库连接场景: 与数据库建立连接后,在函数结束时需要关闭连接。
package main

import (
    "database/sql"
    "fmt"

    _ "github.com/lib/pq" // 以PostgreSQL为例
)

func main() {
    db, err := sql.Open("postgres", "user=pqgotest dbname=pqgotest sslmode=verify-full")
    if err != nil {
        fmt.Println("Error opening database:", err)
        return
    }
    defer db.Close()

    // 执行数据库操作
    // 函数结束时,会关闭数据库连接
}
  1. 解锁互斥锁场景: 当使用互斥锁(sync.Mutex)保护共享资源时,在函数结束时需要解锁互斥锁。
package main

import (
    "fmt"
    "sync"
)

var mu sync.Mutex
var count int

func increment() {
    mu.Lock()
    defer mu.Unlock()
    count++
    fmt.Println("Incremented count:", count)
}

在上述increment函数中,defer mu.Unlock()确保了无论函数如何返回,互斥锁都会被解锁,避免死锁的发生。