Go函数(二)之defer实现代码追踪

本文仅是自己阅读笔记,不正确之处请多包涵和纠正。
原文The way to go

关键字 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 行为被注册时,它们会以逆序执行(类似栈,即后进先出):

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

输出:4 3 2 1 0

1、defer一些常见的应用

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

 defer file.Close()

2、解锁一个加锁的资源

mu.Lock()  
defer mu.Unlock() 

3、打印最终报告

printHeader()  
defer printFooter()

4、关闭数据库链接

// open a database connection  
defer disconnectFromDB()
2、使用 defer 语句实现代码追踪

一个基础但十分实用的实现代码执行追踪的方案就是在进入和离开某个函数打印相关的消息,即可以提炼为下面两个函数:

func trace(s string) { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }

示例 :

package main

import "fmt"

func trace(s string)   { fmt.Println("entering:", s) }
func untrace(s string) { fmt.Println("leaving:", s) }

func a() {
	trace("a")
	defer untrace("a")
	fmt.Println("in a")
}

func b() {
	trace("b")
	defer untrace("b")
	fmt.Println("in b")
	a()
}

func main() {
	b()
}

输出:

entering: b
in b
entering: a
in a
leaving: a
leaving: b
3、使用 defer 语句来记录函数的参数与返回值

示例:

package main

import (
	"io"
	"log"
)

func func1(s string) (n int, err error) {
	defer func() {
		log.Printf("func1(%q) = %d, %v", s, n, err)
	}()
	return 7, io.EOF
}

func main() {
	func1("Go")
}

输出:

Output: 2011/10/04 10:46:11 func1("Go") = 7, EOF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值