1.應用級別,可recover
這些 panic 一般是 邏輯或使用不當導致的運行時錯誤,Go 程序可以用 recover
捕獲并繼續運行:
類型 | 示例 | 描述 |
---|
類型不一致 | atomic.Value 存不同類型 v.Store(100); v.Store("abc") | panic: store of inconsistently typed value |
數組/切片越界 | arr := []int{1,2}; fmt.Println(arr[3]) | panic: runtime error: index out of range |
空指針引用 | var p *int; fmt.Println(*p) | panic: runtime error: invalid memory address or nil pointer dereference |
類型斷言失敗 | var i interface{} = 123; s := i.(string) | panic: interface conversion: int is not string |
映射訪問不存在鍵 | 不會 panic 直接返回零值;但對 nil map 寫入會 panic | |
nil map 寫入 | var m map[int]int; m[1]=1 | panic: assignment to entry in nil map |
channel 關閉寫入 | ch := make(chan int); close(ch); ch<-1 | panic: send on closed channel |
channel 關閉重復 | ch := make(chan int); close(ch); close(ch) | panic: close of closed channel |
| | 阻塞,不 panic(可選) |
runtime 錯誤 | runtime.Gosched() 不會 panic,但 runtime.Goexit() 會終止當前 goroutine | |
死鎖 | 進程內所有協程都在阻塞 | fatal error: all goroutines are asleep - deadlock! |
2. 系統級別錯誤,不可recover
類型 | 示例 | 描述 |
---|
map 并發讀寫 | m := make(map[int]int); go m[1]=1; go _ = m[2] | panic: concurrent map read and map write |
棧溢出 | 無限遞歸函數 | panic: runtime: stack overflow |
內存損壞 | Cgo 直接寫越界內存 | runtime panic,無法 recover |
runtime 系統錯誤 | runtime.Breakpoint() | 調試或系統級 panic,不可 recover |
內存訪問非法 | unsafe 包錯誤操作 | 如訪問非法地址、強制類型轉換出界 |
signal / SIGSEGV | 非法訪問地址 | panic: runtime error: invalid memory address or nil pointer dereference,在系統級別也可能終止進程 |
3. 特殊場景
類型 | 示例 | 描述 |
---|
nil 函數調用 | var f func(); f() | panic: call of nil function |
append 到 nil slice | var s []int; s = append(s, 1) | 不 panic,可以正常工作 |
close nil channel | var ch chan int; close(ch) | panic: close of nil channel |
atomic.Value 讀寫不一致類型 | v.Store(100); v.Store("abc") | panic,可 recover |