唉,只能說C程序員可以接受go的錯誤設計,相比java來說這個設計真的很差勁!
我認為知乎上說的比較中肯的:
1. The key lesson, however, is that errors are values and the full power of the Go programming language is available for processing them.
2. Use the language to simplify your error handling.
But remember: Whatever you do, always check your errors!
Golang這么時尚的語言是沒有類似try..catch 這種異常處理機制,而是使用 panic 和 recover處理異常. 其實相當於python的raise。
golang的異常處理組合 panic,defer,recover,跟java中的try catch finially是類似的。 但是從語言的用戶體驗來說,不怎么好。 但考慮到golang的場景基本是系統高性能層面的,這種精准錯誤處理應該減少那種后遺症bug。
該文章寫的有些亂,歡迎來噴 ! 另外文章后續不斷更新中,請到原文地址查看更新。
使用panic拋出異常,拋出異常后將立即停止當前函數的執行並運行所有被defer的函數,然后將panic拋向上一層,直至程序carsh。但是也可以使用被defer的recover函數來捕獲異常阻止程序的崩潰,recover只有被defer后才是有意義的。
必須注意:
1. defer 需要放在 panic 之前定義,另外recover只有在 defer 調用的函數中才有效。
2. recover處理異常后,邏輯並不會恢復到 panic 那個點去,函數跑到 defer 之后的那個點.
3. 多個 defer 會形成 defer 棧,后定義的 defer 語句會被最先調用
panic (主動爆出異常) 與 recover (收集異常)
recover 用來對panic的異常進行捕獲. panic 用於向上傳遞異常,執行順序是在 defer 之后。
我們舉個含有異常的例子:
1
2
3
4
5
6
7
8
9
10
11
12
|
#xiaorui.cc
func f() {
for {
fmt.Println("1")
a := []string{"a","b"}
fmt.Println(a[3]) // 這里slice越界異常了
/*panic("bug")*/
fmt.Println("4")
time.Sleep(1 * time.Second)
}
}
|
如果你不把這個異常panic recover處理的化,那么就會發生下面的情況.
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#xiaorui.cc
1
panic: runtime error: index out of range
goroutine 1 [running]:
panic(0xda9c0, 0x8201c8090)
/usr/local/go/src/runtime/panic.go:464 +0x3e6
main.f()
/Users/ruifengyun/gg.go:23 +0x33b
main.main()
/Users/ruifengyun/gg.go:16 +0x14
exit status 2
|
下面是處理panic的例子.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
|
package main
import (
"fmt"
"time"
)
func main() {
defer func() { //必須要先聲明defer,否則不能捕獲到panic異常
fmt.Println("2")
if err := recover(); err != nil {
fmt.Println(err) //這里的err其實就是panic傳入的內容,bug
}
fmt.Println("3")
}()
f()
}
func f() {
for {
fmt.Println("1")
panic("bug")
fmt.Println("4") //不會運行的.
time.Sleep(1 * time.Second)
}
}
|
那么上面代碼的運行結果是:
1
2
3
4
5
|
1
2
bug
3
|
上面go代碼實例中,異常是我們通過panic方法主動拋出來的,但如果真的就出現了未知的異常咋辦?
上面go代碼運行結果是:
1
2
3
4
5
6
|
1
xiaorui.cc start
runtime error: index out of range
xiaorui.cc end
end
|
先前沒在意defer recover panic的注意事項,結果各種問題出現了。 不知道go以后會不會有try catch異常模式, 很是期待…
END.
參考資料:
http://xiaorui.cc/2016/03/09/%E5%85%B3%E4%BA%8Egolang%E7%9A%84panic-recover%E5%BC%82%E5%B8%B8%E9%94%99%E8%AF%AF%E5%A4%84%E7%90%86/
http://www.linuxidc.com/Linux/2013-04/83105.htm
http://blog.csdn.net/wuwenxiang91322/article/details/9042503
https://www.zhihu.com/question/27158146