日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Go-defer,panic,recover

發(fā)布時間:2023/12/29 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go-defer,panic,recover 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

defer

語法:

defer function_name()

簡單來講,在defer所在函數(shù)執(zhí)行完所有的代碼之后,會自動執(zhí)行defer的這個函數(shù)。

示例一(基本功能)

package main import "fmt"/* D:\examples>go run helloworld.go first secondD:\examples> */ func main() {defer second()first() }func first() {fmt.Println("first") }func second() {fmt.Println("second") }

示例二(函數(shù)局部性)

package main import "fmt"/* D:\examples>go run helloworld.go first third first secondD:\examples> */ func main() {defer second()first()third() }func first() {fmt.Println("first") }func second() {fmt.Println("second") }func third() {defer first()fmt.Println("third") }

示例三(棧特性)

package main import "fmt"/* D:\examples>go run helloworld.go first third secondD:\examples> */ func main() {defer second()defer third()first() }func first() {fmt.Println("first") }func second() {fmt.Println("second") }func third() {fmt.Println("third") }

使用場景

主要用于資源需要釋放的場景。比如打開一個文件,最后總是要關(guān)閉的。而在打開和關(guān)閉之間,會有諸多的處理,可能會有諸多的if-else、根據(jù)不同的情況需要提前返回。在傳統(tǒng)語言中,return之前都需要一一調(diào)用close()。

而Go的defer就將事情變得簡單了,open()之后,直接就用defer“注冊”一個close()。偽代碼:

f, = os.open(filename) defer f.close() do_something() if (condition_a) {return} do_something_again() if (condition_b) {return} do_further_things()

panic & recover

先給出https://golang.org/pkg/builtin/上的函數(shù)說明。

panic

func panic(v interface{})

The panic built-in function stops normal execution of the current goroutine. When a function F calls panic, normal execution of F stops immediately. Any functions whose execution was deferred by F are run in the usual way, and then F returns to its caller. To the caller G, the invocation of F then behaves like a call to panic, terminating G’s execution and running any deferred functions. This continues until all functions in the executing goroutine have stopped, in reverse order. At that point, the program is terminated and the error condition is reported, including the value of the argument to panic. This termination sequence is called panicking and can be controlled by the built-in function recover.

recover

func recover() interface{}

The recover built-in function allows a program to manage behavior of a panicking goroutine. Executing a call to recover inside a deferred function (but not any function called by it) stops the panicking sequence by restoring normal execution and retrieves the error value passed to the call of panic. If recover is called outside the deferred function it will not stop a panicking sequence. In this case, or when the goroutine is not panicking, or if the argument supplied to panic was nil, recover returns nil. Thus the return value from recover reports whether the goroutine is panicking.

要點

  • panic相當于一個運行時異常
  • 遇到panic的時候,會停止當前函數(shù)剩下來的語句,但在退出該函數(shù)之前,會執(zhí)行defer的語句
  • 依據(jù)函數(shù)調(diào)用層次,panic依次終止每個函數(shù),直至main()。

panic示例

package main import "fmt"/* D:\examples>go run helloworld.go f.1 g.1 h.1 h.defer() g.defer() panic: panic in h()goroutine 1 [running]: panic(0x495360, 0xc04203a230)C:/Go/src/runtime/panic.go:500 +0x1af main.h()D:/examples/helloworld.go:54 +0x12b main.g()D:/examples/helloworld.go:45 +0xee main.f()D:/examples/helloworld.go:38 +0xab main.main()D:/examples/helloworld.go:29 +0x1b exit status 2D:\examples> */ func main() {f() // Line Number: 29 }func final_print(msg string) {fmt.Println(msg) }func f() {fmt.Println("f.1")g() // Line Number: 38fmt.Println("f.2") }func g() {defer final_print("g.defer()")fmt.Println("g.1")h() // Line Number: 45fmt.Println("g.2") }func h() {defer final_print("h.defer()")fmt.Println("h.1")panic("panic in h()") // Line Number: 52fmt.Println("h.2") }

panic & defer & recover

recover相當于try-catch的catch部分,使得panic不再傳遞。而defer相當于try-catch-final的final部分。

package main import "fmt"/* D:\examples>go run helloworld.go f.1 g.1 h.1 h.defer() g.defer() panic in h() f.2D:\examples> */ func main() {f() }func final_print(msg string) {fmt.Println(msg) }func f() {fmt.Println("f.1")g()fmt.Println("f.2") }func g() {defer func() {str := recover()fmt.Println(str)}()defer final_print("g.defer()")fmt.Println("g.1")h()fmt.Println("g.2") }func h() {defer final_print("h.defer()")fmt.Println("h.1")panic("panic in h()")fmt.Println("h.2") }

獲取數(shù)組元素

接下來再給一個例子,獲取數(shù)組元素,處理數(shù)組訪問越界的問題。

package main import "fmt"/* D:\examples>go run helloworld.go a[0]=1[true] a[1]=2[true] a[2]=3[true] a[3]=4[true] a[4]=5[true] runtime error: index out of range [set to default value -1] a[5]=-1[false] runtime error: index out of range [set to default value -1] a[6]=-1[false] runtime error: index out of range [set to default value -1] a[7]=-1[false] runtime error: index out of range [set to default value -1] a[8]=-1[false] runtime error: index out of range [set to default value -1] a[9]=-1[false]D:\examples> */ func main() {a := [5]int {1,2,3,4,5}for i := 0; i < 10; i++ {item, ok := get(i, a)fmt.Printf("a[%d]=%d[%v]\n", i, item, ok)} }func get(i int, a [5]int) (ret int, ok bool) {ok = true defer func() {err := recover()if err != nil {fmt.Println(err, "[set to default value -1]")ret = -1ok = false}}() ret = a[i]return }

總結(jié)

以上是生活随笔為你收集整理的Go-defer,panic,recover的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。