小熊今天有意外收穫,忍不住給大家分享我愉快的心情!昨天中午下樓取外賣的時候被乙個同事認出來了,他問我:「是不是【程式設計三分鐘】的作者,文章寫的不錯」。
今天想和大家聊聊golang
的異常處理
在go
語言裡是沒有try catch
的概念的,因為try catch
會消耗更多資源,而且不管從try
裡面哪個地方跳出來,都是對**正常結構的一種破壞。
所以go
語言的設計思想中主張
所以異常應該總是掌握在我們的手上,保證每次操作產生的影響達到最小,保證程式即使部分地方出現問題,也不會影響整個程式的執行,及時的處理異常,這樣就可以減輕上層處理異常的壓力。
同時也不要讓未知的異常使你的程式崩潰。
我們應該讓異常以這樣的形式出現
func demo() (int, error)
我們應該讓異常以這樣的形式處理(衛述語句)
_,err := errordemo()
if err!=nil
比如程式有乙個功能為除法的函式,除數不能為0
,否則程式為出現異常,我們就要提前判斷除數,如果為0
返回乙個異常。那他應該這麼寫。
func divisionint(a, b int) (int, error)
return a / b, nil
}
這個函式應該被這麼呼叫
a, b := 4, 0
res, err := divisionint(a, b)
if err != nil
fmt.println(a, "除以", b, "的結果是 ", res)
可以注意到上面的兩個知識點
只要記得這些,你就掌握了自定義異常的基本方法。
但是errors.new("字串")
的形式我不建議使用,因為他不支援字串格式化功能,所以我一般使用fmt.errorf
來做這樣的事情。
err = fmt.errorf("產生了乙個 %v 異常", "喝太多")
上面的異常資訊只是簡單的返回了乙個字串而已,想在報錯的時候保留現場,得到更多的異常內容怎麼辦呢?這就要看看errors
的內部實現了。其實相當簡單。
errors
實現了乙個叫error
的介面,這個介面裡就乙個error
方法且返回乙個string
,如下
type error inte***ce
只要結構體實現了這個方法就行,原始碼的實現方式如下
type errorstring struct
func (e *errorstring) error() string
// 多乙個函式當作建構函式
func new(text string) error
}
所以我們只要擴充下自定義error
的結構體欄位就行了。
這個自定義異常可以在報錯的時候儲存一些資訊,供外部程式使用
type fileerror struct
// 初始化函式
func newfileerror(op string, name string, path string) *fileerror
}// 實現介面
func (f *fileerror) error() string
呼叫
f := newfileerror("讀", "readme.md", "/home/how_to_code/readme.md")
fmt.println(f.error())
輸出
路徑為 /home/how_to_code/readme.md 的檔案 readme.md,在 讀 操作時出錯
上面說的內容很簡單,在工作裡也是最常用的,下面說一些拓展知識。
go
中有一種延遲呼叫語句叫defer
語句,它在函式返回時才會被呼叫,如果有多個defer
語句那麼它會被逆序執行。
比如下面的例子是在乙個函式內的三條語句,他是這麼怎麼執行的呢?
defer fmt.println("see you next time!")
defer fmt.println("close all connect")
fmt.println("hei boy")
輸出如下, 可以看到兩個defer
在程式的最後才執行,而且是逆序。
hei boy
close all connect
see you next time!
這一節叫異常處理詳解,終歸是圍繞異常處理來講述知識點,defer
延遲呼叫語句的用處是在程式執行結束,甚至是崩潰後,仍然會被呼叫的語句,通常會用來執行一些告別操作,比如關閉連線,釋放資源(類似於c++
中的析構函式)等操作。
涉及到defer
的操作
這些操作也是非常容易被人忘記的操作,為了保證不會忘記,建議在函式的一開始就放置defer
語句。
剛剛有說到defer
是崩潰後,仍然會被呼叫的語句,那程式在什麼情況下會崩潰呢?
go
的型別系統會在編譯時捕獲很多異常,但有些異常只能在執行時檢查,如陣列訪問越界、空指標引用等。這些執行時異常會引起painc
異常(程式直接崩潰退出)。然後在退出的時候呼叫當前goroutine
的defer
延遲呼叫語句。
有時候在程式執行缺乏必要的資源的時候應該手動觸發宕機(比如配置檔案解析出錯、依賴某種獨有庫但該作業系統沒有的時候)
defer fmt.println("關閉檔案控制代碼")
panic("人工建立的執行時異常")
報錯如下
然後再借助運維監控系統對日誌的監控,傳送告警給運維、開發人員,進行緊急修復。
語法如下:
func divisionintrecover(a, b int) (ret int)
}()return a / b
}
呼叫
var res int
datas := struct ,
, }for _, v := range datas
fmt.println(v.a, "/", v.b, "計算結果為:", res)
}
輸出結果
runtime error: integer divide by zero
2 / 2 計算結果為: 1
這就是go
異常處理,我所能想到和找到的全部內容了,希望你在工作中用的更順手。 golang 異常處理
一般異常可以直接用 errors 包接收以及捕獲能遇見的異常,func test1 a,b int value int,err error else golang 允許多個返回值 error 常用語自定義異常丟擲返回異常包含一般異常 常用於不可預見不知情遇見的異常 panic可在程式中直接呼叫 pa...
C 異常處理 多重catch塊
有時候只使用乙個異常處理不完全解決程式 現的異常,需要多個異常處理,這就需要多重catch來實現。一段 可能會生成多個異常當引發異常時,會按順序來檢視每個 catch 語句,並執行第乙個型別與異常型別匹配的語句執行其中的一條 catch 語句之後,其他的 catch 語句將被忽略。多重catch語法...
golang 錯誤處理與異常
golang 中的錯誤處理的哲學和 c 語言一樣,函式通過返回錯誤型別 error 或者 bool 型別 不需要區分多種錯誤狀態時 表明函式的執行結果,呼叫檢查返回的錯誤型別值是否是 nil 來判斷呼叫結果。golang 中內建的錯誤型別 error 是乙個介面型別,自定義的錯誤型別也必須實現為 e...