Ding-Log
  • Ding Blog
  • Life
    • My Tool Box
  • Golang
    • Basic
      • Go语言学习笔记
        • Go语言 Channel
        • Go语言 goroutine
        • Go语言 如何写Godoc
        • Go语言panic, recover
        • Go语言的Defer函数
        • Go语言的闭包
        • Go语言接口(Golang - Interface)
        • Go语言的面向对象
      • Go语言爬虫
        • Go语言爬虫 - 广度优先算法
      • Map
    • Web
      • Example to handle GET and POST request in Golang
    • Exercism
      • Isogram
      • ETL
      • Accumulate
      • Scrabble Score
  • SAP
    • SAPUI5&Fiori
      • How to prepare C_FIORDEV_20 SAP Certified Development Associate — SAP Fiori Application Developer
      • SAPUI5 sap.ui.define and sap.ui.require
      • SAPUI5 Models and Binding
      • SAPUI5 MVC Walkthrough
    • ABAP
      • Working with Internal Tables
      • 关于使用内部表的时候的一些注意事项
      • Error Handling
  • Log
Powered by GitBook
On this page
  • Defer的特点
  • 确保调用在函数结束时发生
  • 参数在defer语句时计算 / defer列表为后进先出
  • 何时使用defer

Was this helpful?

  1. Golang
  2. Basic
  3. Go语言学习笔记

Go语言的Defer函数

Golang defer function

Defer的特点

  • 确保调用在函数结束时发生

  • 参数在defer语句时计算

  • defer列表为后进先出

确保调用在函数结束时发生

下面的例子中,fmt.Println(1)会比fmt.Println(2)晚执行。

func tryDefer() {
	defer fmt.Println(1)
	fmt.Pintln(2)
	panic("error")
}
func main() {//
	tryDefer()
}

再看一个文件的例子

package main

import (
	"fmt"
	"os"
	"bufio"
	"imooc.com/ccmouse/learngo/lang/functional/fib"
)

func writeFile(filename string) {
	file, err := os.OpenFile(filename,
		os.O_EXCL|os.O_CREATE|os.O_WRONLY, 0666)

	if err != nil {
		if pathError, ok := err.(*os.PathError); !ok {
			panic(err)
		} else {
			fmt.Printf("%s, %s, %s\n",
				pathError.Op,
				pathError.Path,
				pathError.Err)
		}
		return
	}
	defer file.Close()

	writer := bufio.NewWriter(file)
	defer writer.Flush()

	f := fib.Fibonacci()
	for i := 0; i < 20; i++ {
		fmt.Fprintln(writer, f())
	}
}

func main() {
	writeFile("fib.txt")
}

参数在defer语句时计算 / defer列表为后进先出

关于参数在defer语句时计算,可以看这个例子。

package main

import (
	"fmt"
	"os"

	"bufio"

	"imooc.com/ccmouse/learngo/lang/functional/fib"
)

func tryDefer() {
	for i := 0; i < 100; i++ {
		defer fmt.Println(i)
		if i == 30 {
			panic("printed too many")
		}
	}
}

func main() {
	tryDefer()
}

得到下面的结果,可以看到defer是从10开始打印的,说明后进先出。

然后程序在10的时候停住了,但是并没有打印10个10,说明参数在defer语句时计算。

10
9
8
7
6
5
4
3
2
1
0
panic: printed too many

何时使用defer

  • open/close

  • lock/unlock

  • printheader/pringfooter

PreviousGo语言panic, recoverNextGo语言的闭包

Last updated 5 years ago

Was this helpful?