欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

go語言優(yōu)雅地處理error工具及技巧詳解

 更新時間:2022年11月24日 09:27:37   作者:洛天楓  
這篇文章主要為大家介紹了go語言優(yōu)雅地處理error工具及技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

引言

我看到很多 golang 社區(qū)的開發(fā)者,特別是因為它的簡單性而被吸引的開發(fā)者,對 golang 中的事情應(yīng)該如何處理做出了一些快速的判斷。

其中一件事就是錯誤處理。由于目前大多數(shù)語言的開發(fā)者都來自于 OOP 背景,他們習(xí)慣于處理異常,或者說"拋出"異常的概念來停止當(dāng)前的應(yīng)用程序的流程,而且他們大多認(rèn)為這也是 golang 的方式,我們必須在出錯的情況下停止我們的應(yīng)用程序的流程。他們錯了!

不要濫用你的工具

我見過很多,我以前也是這樣做的。每當(dāng)有意外情況發(fā)生時,就用 os.exit(1),然后繼續(xù)前進。好吧,這不是使用go的正確方法!

我明白為什么這被廣泛使用,因為大多數(shù)早期的 golang 應(yīng)用程序只是終端工具,而且許多這些工具曾經(jīng)使用 .sh 可執(zhí)行文件來構(gòu)建,我們曾經(jīng)只是退出1;以表示剛剛發(fā)生了一些意外的事情,我們想退出。

我們把這種習(xí)慣帶到了我們的 golang 簡單的終端應(yīng)用中,然后又帶到了復(fù)雜的應(yīng)用中,這只是另一種 Cargo Cult Programming。 我高度鼓勵你在不得不這樣做的情況下,要非常小心,因為它是:

  • 隨著你的應(yīng)用程序的增長,非常難以維護。
  • 最重要的是,不可能對這樣的代碼進行單元測試,這顯然表明它的不潔性。
  • 以這種方式退出將阻止你的任何延遲操作的執(zhí)行,你的程序?qū)⒘⒓唇K止,這可能導(dǎo)致資源泄漏。請考慮一下這個例子:
func main() {
    dbConnection := db.connect("...")
    defer dbConnection.Close() // this operation won't be executed!    
    entity := Entity{}
    err := dbConnection.Save(entity)
    if err != nil {
        os.Exit(1)
    }
}

考慮傳遞你的錯誤

錯誤只是 golang 中的另一種類型,你必須用它們來控制程序的執(zhí)行流程。

為了做到這一點,我們必須在整個程序中傳播這些錯誤,直到適當(dāng)?shù)奶幚睃c。

考慮一個管理訂單的HTTP API,我們想禁止客戶在特定條件下下訂單,例如:

package order
// package errors
var (
    UnableToShipToCountry = errors.New("unable to ship order to the requested country")
)
type Order struct {
    // ... order fields
}
type OrderRepo struct {
    DB db
    // ...
}
func newOrderFromRequest(o OrderRequest) (Order, error) {
    if o.ShippingAddress.Country != "DE" {
	return UnableToShipToCountry
    }    // ... the creation logic
    return Order{...}, nil
}
func (r *OrderRepo)PlaceOrder(o OrderRequest) error {
    order, err := newOrderFromRequest(o)
    if err != nil {
        // don't handle the error here, its handling may differ
        return err
    }    // ... db transaction may also return an error
    return r.db.Save(order)
}

在我們的 http package 中:

package http
http.HandleFunc("/order", func (w http.ResponseWriter, r *http.Request) {
    orderRequest := createOrderRequest(r)
    err := orderRepo.PlaceOrder(orderRequest)
    if errors.Is(err, order.UnableToShipToCountry) {
        w.WriteHeader(http.StatusBadRequest)
        return
    }
    if err != nil {
        // this error in case of DB transaction failure
        w.WriteHeader(http.StatusInternalServerError)
        return
    }    // ...
    w.WriteHeader(http.StatusOK)
})

定制你的錯誤

我們可以創(chuàng)建我們自己的自定義錯誤值,并在我們的程序中使用它,同時考慮添加一些有用的信息,如錯誤跟蹤這可能會給我們的日志增加一個有益的價值,特別是在調(diào)試期間。

type AppErr struct {  
    msg string  
    code int  
    trace string  
}  
func (e AppErr) Error() string {  
    return fmt.Sprintf("Msg: %s, code: %d, trace:\n %s", e.msg, e.code, e.trace)  
}  
func NewAppErr(msg string, code int) AppErr {  
    stackSlice := make([]byte, 512)  
    s := runtime.Stack(stackSlice, false)  
    return AppErr{msg, code, fmt.Sprintf("\n%s", stackSlice[0:s])}  
}

而我們在一個包內(nèi)有這樣一個用例:

package admin  
func A() error {  
    return b()  
}  
func b() error {  
    return NewAppErr("error from b function!", 3)  
}

main.go:

func main() {  
    err := admin.A()
    fmt.Println(err)
}

記錄的錯誤信息將是:

Msg: error from b function!, code: 3, trace:  
goroutine 1 [running]:  
./cmd/app/error.NewAppErr({0x1f42b0, 0x17}, 0x7)  
./cmd/app/error/error.go:16 +0x35  
./cmd/app/admin.b(...)  
./cmd/app/admin/**admin.go:12**  
./cmd/app/admin.A(...)  
./cmd/app/admin/**admin.go:8**  
main.main()  
./cmd/app/**main.go:10** +0x8d

你也可以考慮在生產(chǎn)環(huán)境中關(guān)閉你的跟蹤打印,或者通過檢查其他配置值。

以上就是go語言優(yōu)雅地處理error工具及技巧詳解的詳細(xì)內(nèi)容,更多關(guān)于go語言處理error工具的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言異常處理案例解析

    Go語言異常處理案例解析

    這篇文章主要介紹了Go語言異常處理案例解析,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下
    2021-07-07
  • Go GORM版本2.0新特性介紹

    Go GORM版本2.0新特性介紹

    這篇文章主要為大家介紹了Go GORM版本2.0新特性的使用示例介紹,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 利用Go語言實現(xiàn)在終端繪制小兔子

    利用Go語言實現(xiàn)在終端繪制小兔子

    這篇文章主要為大家詳細(xì)介紹了如何利用Go語言實現(xiàn)在終端繪制小兔子來給大家拜個早年,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-01-01
  • go?test?命令示例詳解

    go?test?命令示例詳解

    go?test是Go用來執(zhí)行測試函數(shù)(test?function)、基準(zhǔn)函數(shù)(benchmark?function)和示例函數(shù)(example?function)的命令,這篇文章主要介紹了go?test?命令,需要的朋友可以參考下
    2023-11-11
  • GO語言實現(xiàn)文件上傳代碼分享

    GO語言實現(xiàn)文件上傳代碼分享

    本文給大家分享的是一則使用golang實現(xiàn)文件上傳的代碼,主要是使用os.Create創(chuàng)建文件,io.Copy來保存文件,思路非常清晰,這里推薦給大家,有需要的小伙伴參考下吧。
    2015-03-03
  • 詳解Golang time包中的結(jié)構(gòu)體time.Time

    詳解Golang time包中的結(jié)構(gòu)體time.Time

    在日常開發(fā)過程中,會頻繁遇到對時間進行操作的場景,使用 Golang 中的 time 包可以很方便地實現(xiàn)對時間的相關(guān)操作,本文先講解一下 time 包中的結(jié)構(gòu)體 time.Time,需要的朋友可以參考下
    2023-07-07
  • Go語言中strings和strconv包示例代碼詳解

    Go語言中strings和strconv包示例代碼詳解

    這篇文章主要介紹了Go語言中strings和strconv包示例代碼詳解 ,非常不錯,具有一定的參考借鑒價值,需要的朋友可以參考下
    2018-11-11
  • 一文搞懂Go語言操作Redis的方法

    一文搞懂Go語言操作Redis的方法

    Redis是一個開源的內(nèi)存數(shù)據(jù)庫,在項目開發(fā)中redis的使用也比較頻繁,本文介紹了Go語言中g(shù)o-redis庫的基本使用。感興趣的小伙伴們可以參考借鑒一下
    2022-09-09
  • 詳解Go語言中配置文件使用與日志配置

    詳解Go語言中配置文件使用與日志配置

    這篇文章主要為大家詳細(xì)講解一下Go語言中調(diào)整項目目錄結(jié)構(gòu)、增加配置文件使用和增加日志配置的方法,文中示例代碼講解詳細(xì),需要的可以參考一下
    2022-06-06
  • Go語言使用讀寫OPC詳解

    Go語言使用讀寫OPC詳解

    這篇文章主要介紹了Go語言使用讀寫OPC詳解,圖文講解的很清晰,有感興趣的同學(xué)可以學(xué)習(xí)下
    2021-03-03

最新評論