返回

你不可不知的 Go 语言 defer 函数

后端

defer函数的作用

在Go语言中,defer语句可以让你在函数返回前执行一些指定的函数调用。这些函数调用会在函数返回前执行,即使是发生了panic或return。这对于一些常见的场景非常有用,例如:

  • 释放资源:defer语句可以用来确保资源在函数返回前被释放,即使发生了panic或return。
  • 记录日志:defer语句可以用来记录函数的执行时间、参数或其他信息,即使发生了panic或return。
  • 关闭文件:defer语句可以用来关闭打开的文件,即使发生了panic或return。

defer函数的语法

defer语句的语法非常简单:

defer func() {
  // 要延迟执行的代码
}

其中,func()是延迟执行的函数,它可以接受任意数量的参数,也可以返回任意数量的值。

defer函数的用法

defer语句可以用来延迟执行任何函数调用,包括内置函数、用户自定义函数、方法调用等。defer语句可以放在函数的任何位置,但通常会放在函数的最后。

defer函数的应用场景

defer函数可以应用于各种场景中,以下是一些常见的应用场景:

  • 释放资源:defer语句可以用来确保资源在函数返回前被释放,即使发生了panic或return。例如,以下代码使用defer语句来确保文件在函数返回前被关闭:
func OpenFile(name string) (*File, error) {
  file, err := os.Open(name)
  if err != nil {
    return nil, err
  }
  defer file.Close()
  return file, nil
}
  • 记录日志:defer语句可以用来记录函数的执行时间、参数或其他信息,即使发生了panic或return。例如,以下代码使用defer语句来记录函数的执行时间:
func Sum(numbers ...int) int {
  start := time.Now()
  defer func() {
    elapsed := time.Since(start)
    log.Printf("Sum took %s", elapsed)
  }()
  sum := 0
  for _, number := range numbers {
    sum += number
  }
  return sum
}
  • 关闭文件:defer语句可以用来关闭打开的文件,即使发生了panic或return。例如,以下代码使用defer语句来关闭文件:
func ReadFile(name string) ([]byte, error) {
  file, err := os.Open(name)
  if err != nil {
    return nil, err
  }
  defer file.Close()
  data, err := ioutil.ReadAll(file)
  if err != nil {
    return nil, err
  }
  return data, nil
}

defer函数的注意事项

在使用defer语句时,需要注意以下几点:

  • defer语句只能延迟函数调用,不能延迟其他类型的语句,例如变量声明、赋值语句等。
  • defer语句中的函数调用会在函数返回前执行,即使是发生了panic或return。
  • defer语句中的函数调用是按照后进先出的顺序执行的,即最后压入栈的函数会最先执行。
  • defer语句中的函数调用可能会导致函数返回多个值,但这些值只能通过返回值来获取,不能通过参数来获取。