10个Go的defer 技巧

Go的defer关键字是一个强大的工具,它允许你指定一个函数调用在以后执行,通常是在周围的函数返回之后。虽然看起来是一个简单的概念,但defer关键字可以用几种高级的方式来提高Go代码的效率和可靠性。
defer关键字的作用是当外围函数返回之后才执行被推迟的函数。
首先记住一点重要的原则:defer函数在外围函数返回之后,以后进先出(LIFO)的原则执行。
在这篇文章中,我们将探讨在Go中使用defer的十个技巧。从取消事件和释放资源到打印函数使用的时间和从panic中恢复,这些技巧将帮助你把你的Go技能提高到一个新的水平。无论你是想了解更多关于defer的初学者,还是想拓展知识面的经验丰富的开发者,这篇文章都能满足你的需求。

1.推迟一个函数调用,在周围的函数返回后执行:

func main() {
 defer fmt.Println("This will be printed after main returns")
}

2.推迟一个函数调用,按照它们被推迟的相反顺序执行:

func main() {
	defer_call()
}

func defer_call() {
	defer func() { fmt.Println("打印前") }()
	defer func() { fmt.Println("打印中") }()
	defer func() { fmt.Println("打印后") }()
}

3.即使发生恐慌,也要推迟一个函数的调用执行:

func main() {
 defer func() {
  if r := recover(); r != nil {
   fmt.Println("从 panic 中恢复:", r)
  }
 }()

 // This will cause a panic
 a := []int{1, 2, 3}
 fmt.Println(a[3])
}

4.推迟函数调用以关闭一个文件:

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

 // Do something with the file
}

5.推迟一个函数调用来解锁一个mutex

func main() {
 var mutex sync.Mutex
 mutex.Lock()
 defer mutex.Unlock()

 // Do something that requires the mutex to be locked
}

6.推迟一个函数调用来减少一个 waitgroup

func main() {
 var wg sync.WaitGroup
 wg.Add(1)
 defer wg.Done()

 // Do something that requires the wait group to be waited on
 wg.Wait()
}

7.推迟一个函数调用来回滚一个事务:

func main() {
 tx, err := db.Begin()
 if err != nil {
  fmt.Println(err)
  return
 }
 defer tx.Rollback()

 // Do something with the transaction
 err = tx.Commit()
 if err != nil {
  fmt.Println(err)
  return
 }
}

8.推迟函数调用以释放一个资源:

func main() {
 resource, err := AcquireResource()
 if err != nil {
  fmt.Println(err)
  return
 }
 defer ReleaseResource(resource)

 // Do something with the resource
}

9.推迟一个函数的调用,打印一个函数所花费的时间:

func main() {
 start := time.Now()
 defer fmt.Printf("Time taken: %v\n", time.Since(start))

 // Do something that takes time
}

10.执行多个 defer 方法

首先记住一点重要的原则:defer函数在外围函数返回之后,以后进先出(LIFO)的原则执行。

defer fmt.Println("A")
defer fmt.Println("B")
defer fmt.Println("C")

总之,Go中的defer关键字允许你将一个函数调用安排在一个较晚的时间点上执行,即在周围函数返回之后。这对于清理资源、释放锁、回滚事务以及执行其他类型的延迟执行等任务非常有用。
defer语句可以被多次使用,延迟的函数调用将按照后进先出的顺序执行。这对堆叠多个延迟任务很有用,如关闭多个文件或释放多个锁。
总的来说,defer关键字是一个强大而方便的工具,可以确保Go程序中的某些任务总是被执行,而不管程序的流程如何。

面试题

func main() {
	defer_call()
}

func defer_call() {
	defer func() { fmt.Println("打印前") }()
	defer func() { fmt.Println("打印中") }()
	defer func() { fmt.Println("打印后") }()

	panic("触发异常")
}

output:

// 打印后 
// 打印中 
// 打印前 
// panic: 触发异常 
// goroutine 1 [running]: 
// main.defer_call() 
// C:/Users/Administrator/go/src/github.com/timliudream/go-test/Interview/1/interview1.go:16 +0xe7 
// main.main() 
// C:/Users/Administrator/go/src/github.com/timliudream/go-test/Interview/1/interview1.go:8 +0x27

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mldxxxxll5

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值