日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

go語言中的defer關鍵字_Golang

作者:taadis ? 更新時間: 2022-09-21 編程語言

我是誰

defer?- 顧名思義翻譯過來叫?延遲, 所以我們通常稱呼?defer func()?這樣?defer?后面緊跟的函數為?延遲函數.

作者注: 不過從實際應用來講, 延遲函數通常用來做一些函數最終返回前的一些收尾工作, 所以稱呼為收尾函數其實更貼切.

三圍幾何

defer?有其獨特的一面, 了解其個性, 才能更好的下手。

延遲性

顧名思義, 既然叫延遲函數, 那么肯定具備延遲性.

我們來看看怎么個延遲法,

defer_defer.go

// defer_defer.go
package main

import (
	"fmt"
)

func main() {
	foo()
}

func foo() {
	fmt.Println(1)
	defer fmt.Println(2)
	fmt.Println(3)
}

// go run defer_defer.go
// 1
// 3
// 2

可以看到?defer?定義的延遲函數最后才執行.

再來個例子, 如果一個函數內出現多個延遲函數, 延遲函數的執行順序又是怎么樣的呢?

defer_filo.go

// defer_filo.go
package main

import (
	"fmt"
)

func main() {
	foo()
}

func foo() {
	defer fmt.Println(1)
	defer fmt.Println(2)
	defer fmt.Println(3)
}

// go run defer_filo.go
// 3
// 2
// 1

可以看到先定義的延遲函數后執行, 后定義的延遲函數先執行, 符合棧 (stack) 的先進后出 (FILO) 原則.

影響性

直接看代碼,

defer_impact.go

// defer_impact.go
package main

import (
	"fmt"
)

func main() {
	fmt.Println(foo())
}

func foo() (result int) {
	defer func() {
		result++
	}()
	return 0
}

// go run defer_defer.go
// 1

結果是不是跟想象有點不一樣? 上述?foo()?可以改寫為下:

func foo() (result int) {
	result = 0
	result++
	return
}

go 中的?return?語句不是原子操作.

go 中?return?語句的操作過程為:

  • 設置返回值
  • 執行延遲函數
  • 真正?return

所以延遲函數會影響主函數的返回值, 當然還要區分具名返回值/匿名返回值, 后話再說.

確定性

延遲函數的參數值, 在延遲函數首次出現時就確定了, 不受后續操作的影響.

我們來個例子:

defer_parameters.go

// defer_parameters.go
package main

import (
	"fmt"
)

func main() {
	foo()
}

func foo() {
	number := 1
	defer fmt.Println(number)
	number = 2
	return
}

// go run defer_parameters.go
// 1

能做啥

  • 打開數據鏈接, 要記得關閉, 可以用?defer
  • 操作完內存資源, 要記得釋放, 可以用?defer
  • 想改變主函數的具名返回值, 可以用?defer?- 通常不會這么干
  • 想奇淫技巧, 可以用?defer?- 偶爾 show 偶爾爽, 一直 show 一直爽
  • 想搞事情, 可以用?defer?- 請自行確保生命和財產安全
  • ...

原文鏈接:https://www.cnblogs.com/taadis/p/go-defer.html

欄目分類
最近更新