Go语法之函数 defer使用

上文我们讲了Go语法的特殊之处,本文讲述Go语法之函数 defer使用。

延迟调用defer是什么?

关键字 defer 的用法类似于面向对象编程语言 Java 和 C# 的 finally 语句块,它一般用于释放某些已分配的资源

  • defer用于注册一个延迟调用(在函数返回之前调用)。
  • defer典型的应用场景是释放资源,比如关闭文件句柄,释放数据库连接等。
  • 如果同一个函数里有多个defer,则后注册的先执行。
  • defer后可以跟一个func,func内部如果发生panic,会把panic暂时搁置,当把其他defer执行完之后再来执行这个。
  • defer后不是跟func,而直接跟一条执行语句,则相关变量在注册defer时被拷贝或计算。
func basic() {
    fmt.Println("A")
    defer fmt.Println(1) fmt.Println("B")
    //如果同一个函数里有多个defer,则后注册的先执行
    defer fmt.Println(2)
    fmt.Println("C")
}
func defer_exe_time() (i int) {
	i = 9
	defer func() { //defer后可以跟一个func
		fmt.Printf("first i=%d\n", i) //打印5,而非9。充分理解“defer在函数返回前执行”的含义,不是在“return语句前执行defer”
	}()
	defer func(i int) {
		fmt.Printf("second i=%d\n", i) //打印9
	}(i)
	defer fmt.Printf("third i=%d\n", i) //defer后不是跟func,而直接跟一条执行语句,则相关变量在注册defer时被拷贝或计算
	return 5
}

关键字 defer 允许我们推迟到函数返回之前(或任意位置执行 return 语句之后)一刻才执行某个语句或函数(为什么要在返回之后才执行这些语句?因为 return 语句同样可以包含一些操作,而不是单纯地返回某个值)。

package main
import "fmt"
 
func main() {
    function1()
}
 
func function1() {
    fmt.Printf("In function1 at the top\n")
    defer function2()
    fmt.Printf("In function1 at the bottom!\n")
}
 
func function2() {
    fmt.Printf("function2: Deferred until the end of the calling function!")
}

输出:

In Function1 at the top
In Function1 at the bottom!
Function2: Deferred until the end of the calling function!

将 defer 关键字去掉并对比输出结果。
使用 defer 的语句同样可以接受参数,下面这个例子就会在执行 defer 语句时打印 0:

func a() {
    i := 0
    defer fmt.Println(i)
    i++
    return
}

当有多个 defer 行为被注册时,它们会以逆序执行(类似栈,即后进先出):

func f() {
    for i := 0; i < 5; i++ {
        defer fmt.Printf("%d ", i)
    }
}

上面的代码将会输出:4 3 2 1 0。

关键字 defer 允许我们进行一些函数执行完成后的收尾工作,例如:

关闭文件流 (详见 第 12.2 节)

// open a file  
defer file.Close()

解锁一个加锁的资源

mu.Lock()  
defer mu.Unlock() 

打印最终报告

printHeader()  
defer printFooter()

关闭数据库链接

// open a database connection  
defer disconnectFromDB()

相关推荐

  1. Go语法函数 defer使用

    2024-03-11 13:34:03       21 阅读
  2. 理解Go语言中的defer

    2024-03-11 13:34:03       40 阅读
  3. Go】探索Go语言中的关于defer的应用

    2024-03-11 13:34:03       22 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-11 13:34:03       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-11 13:34:03       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-11 13:34:03       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-11 13:34:03       20 阅读

热门阅读

  1. 大数据开发(Hadoop面试真题-卷六)

    2024-03-11 13:34:03       24 阅读
  2. Node.js概述与安装和运行

    2024-03-11 13:34:03       20 阅读
  3. springboot文件上传

    2024-03-11 13:34:03       20 阅读
  4. 《Webpack 报错》Can‘t find stylesheet to import

    2024-03-11 13:34:03       22 阅读
  5. 程序员如何选择职业赛道?

    2024-03-11 13:34:03       26 阅读
  6. 微服务面试题

    2024-03-11 13:34:03       22 阅读
  7. (C++) 如何设计一个安全的pop函数

    2024-03-11 13:34:03       23 阅读
  8. 消息中间件面试题-参考回答

    2024-03-11 13:34:03       22 阅读