最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

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

引言

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

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

不要濫用你的工具

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

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

我們把這種習(xí)慣帶到了我們的 golang 簡(jiǎn)單的終端應(yīng)用中,然后又帶到了復(fù)雜的應(yīng)用中,這只是另一種 Cargo Cult Programming。 我高度鼓勵(lì)你在不得不這樣做的情況下,要非常小心,因?yàn)樗牵?/p>

  • 隨著你的應(yīng)用程序的增長(zhǎng),非常難以維護(hù)。
  • 最重要的是,不可能對(duì)這樣的代碼進(jìn)行單元測(cè)試,這顯然表明它的不潔性。
  • 以這種方式退出將阻止你的任何延遲操作的執(zhí)行,你的程序?qū)⒘⒓唇K止,這可能導(dǎo)致資源泄漏。請(qǐng)考慮一下這個(gè)例子:
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)
    }
}

考慮傳遞你的錯(cuò)誤

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

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

考慮一個(gè)管理訂單的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)
})

定制你的錯(cuò)誤

我們可以創(chuàng)建我們自己的自定義錯(cuò)誤值,并在我們的程序中使用它,同時(shí)考慮添加一些有用的信息,如錯(cuò)誤跟蹤這可能會(huì)給我們的日志增加一個(gè)有益的價(jià)值,特別是在調(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])}  
}

而我們?cè)谝粋€(gè)包內(nèi)有這樣一個(gè)用例:

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)
}

記錄的錯(cuò)誤信息將是:

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)閉你的跟蹤打印,或者通過(guò)檢查其他配置值。

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

相關(guān)文章

  • Go設(shè)計(jì)模式之狀態(tài)模式圖文詳解

    Go設(shè)計(jì)模式之狀態(tài)模式圖文詳解

    狀態(tài)模式是一種行為設(shè)計(jì)模式, 讓你能在一個(gè)對(duì)象的內(nèi)部狀態(tài)變化時(shí)改變其行為, 使其看上去就像改變了自身所屬的類一樣,本文將通過(guò)一些圖片來(lái)給大家詳細(xì)的介紹一下Go的狀態(tài)模式,需要的朋友可以參考下
    2023-08-08
  • golang 40行代碼實(shí)現(xiàn)通用協(xié)程池

    golang 40行代碼實(shí)現(xiàn)通用協(xié)程池

    golang協(xié)程機(jī)制很方便的解決了并發(fā)編程的問(wèn)題,但是協(xié)程并不是沒有開銷的,所以也需要適當(dāng)限制一下數(shù)量。這篇文章主要介紹了golang 40行代碼實(shí)現(xiàn)通用協(xié)程池,需要的朋友可以參考下
    2018-08-08
  • 服務(wù)器端Go程序?qū)﹂L(zhǎng)短鏈接的處理及運(yùn)行參數(shù)的保存

    服務(wù)器端Go程序?qū)﹂L(zhǎng)短鏈接的處理及運(yùn)行參數(shù)的保存

    這篇文章主要介紹了服務(wù)器端Go程序?qū)﹂L(zhǎng)短鏈接的處理及運(yùn)行參數(shù)的保存,這里針對(duì)使用Go語(yǔ)言編寫的Socket服務(wù)器進(jìn)行實(shí)例說(shuō)明,需要的朋友可以參考下
    2016-03-03
  • GO語(yǔ)言的數(shù)組array與切片slice詳解

    GO語(yǔ)言的數(shù)組array與切片slice詳解

    這篇文章主要介紹了GO語(yǔ)言的數(shù)組array與切片slice,包括了GO語(yǔ)言數(shù)組定義賦值,GO語(yǔ)言多維數(shù)組,GO語(yǔ)言切片等知識(shí)點(diǎn)需要的朋友可以參考下
    2022-12-12
  • 淺談go build后加文件和目錄的區(qū)別

    淺談go build后加文件和目錄的區(qū)別

    這篇文章主要介紹了淺談go build后加文件和目錄的區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)詳解

    Go語(yǔ)言函數(shù)的延遲調(diào)用(Deferred Code)詳解

    本文將介紹Go語(yǔ)言函數(shù)和方法中的延遲調(diào)用,正如名稱一樣,這部分定義不會(huì)立即執(zhí)行,一般會(huì)在函數(shù)返回前再被調(diào)用,我們通過(guò)一些示例來(lái)了解一下延遲調(diào)用的使用場(chǎng)景
    2022-07-07
  • Go語(yǔ)言的文件名、標(biāo)識(shí)符、關(guān)鍵字和包基礎(chǔ)教程

    Go語(yǔ)言的文件名、標(biāo)識(shí)符、關(guān)鍵字和包基礎(chǔ)教程

    Go的關(guān)鍵字不能被用作標(biāo)識(shí)符,這是一個(gè)重要的限制,以避免命名沖突和語(yǔ)法混淆,這篇文章主要給大家介紹了關(guān)于Go語(yǔ)言文件名、標(biāo)識(shí)符、關(guān)鍵字和包的相關(guān)資料,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2024-06-06
  • golang利用函數(shù)閉包實(shí)現(xiàn)簡(jiǎn)單的中間件

    golang利用函數(shù)閉包實(shí)現(xiàn)簡(jiǎn)單的中間件

    中間件設(shè)計(jì)模式是一種常見的軟件設(shè)計(jì)模式,它在許多編程語(yǔ)言和框架中被廣泛應(yīng)用,這篇文章主要為大家介紹一下golang利用函數(shù)閉包實(shí)現(xiàn)一個(gè)簡(jiǎn)單的中間件,感興趣的可以了解下
    2023-10-10
  • golang語(yǔ)言中wasm 環(huán)境搭建的過(guò)程詳解

    golang語(yǔ)言中wasm 環(huán)境搭建的過(guò)程詳解

    將 golang 打包為 WASM,通常有兩種打包方式,一種是 golang 自帶的,另外是使用 tinygo ,接下來(lái)通過(guò)本文給大家介紹golang語(yǔ)言中wasm 環(huán)境搭建的過(guò)程,感興趣的朋友一起看看吧
    2021-11-11
  • Go語(yǔ)言中切片使用的注意事項(xiàng)小結(jié)

    Go語(yǔ)言中切片使用的注意事項(xiàng)小結(jié)

    切片是引用類型,相信對(duì)大家來(lái)說(shuō)都不陌生,下面這篇文章主要給大家總結(jié)介紹了關(guān)于Go語(yǔ)言中切片使用的一些注意事項(xiàng),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。
    2018-01-01

最新評(píng)論

崇明县| 通辽市| 新津县| 杭锦后旗| 桑植县| 华容县| 皮山县| 泸水县| 通州区| 鹤庆县| 杭锦旗| 乐至县| 灵山县| 蓝山县| 隆德县| 临桂县| 治多县| 多伦县| 灵山县| 海晏县| 兴仁县| 东阳市| 顺平县| 喀什市| 惠州市| 周宁县| 建昌县| 呼玛县| 资中县| 辽中县| 黔西县| 普宁市| 济阳县| 东乡| 同德县| 策勒县| 响水县| 通辽市| 都匀市| 长葛市| 天津市|