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

從錯誤中學(xué)習(xí)改正Go語言六個壞習(xí)慣提高編程技巧

 更新時間:2024年01月16日 10:53:33   作者:Slagga  
這篇文章主要為大家介紹了從錯誤中學(xué)習(xí)改正Go語言五個壞習(xí)慣提高編程技巧示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

從他人的錯誤中學(xué)習(xí),通過本指南避免常見陷阱和壞習(xí)慣,提高你的 Go 編程技巧

在 Go 語言中,就像在任何編程語言中一樣,了解常見陷阱和壞習(xí)慣是編寫干凈、高效代碼的關(guān)鍵。

盡管下面列出的某些做法通常被認(rèn)為是不好的,但在某些情況下它們可以有效地使用。 這篇文章旨在提醒大家這些做法的問題所在,并教導(dǎo)如何避免這些陷阱。

讓我們深入探討。

1. 使用 init()

在 Go 中,init()函數(shù)是在主函數(shù)之前執(zhí)行的特殊函數(shù)。

“如果在任何包中初始化是如此重要的過程,為什么在 Go 中init()被認(rèn)為是一種不好的實踐?” —— 讀者

是的,雖然init()函數(shù)有助于在運(yùn)行核心邏輯之前進(jìn)行初始化,但它們的執(zhí)行順序可能難以理解。 這可能會導(dǎo)致關(guān)于初始化順序的混亂。

如果兩個模塊互相依賴于初始化并位于不同的包中,則可能會增加復(fù)雜性并需要額外的代碼添加等待邏輯。然而,這也可能導(dǎo)致死鎖的可能性。

另一個init()函數(shù)的問題是它會使測試更加困難。因為它們自動運(yùn)行,很難控制它們何時執(zhí)行,這可能使設(shè)置測試用例和測試代碼行為變得具有挑戰(zhàn)性。

我遇到了一個問題,我的服務(wù)從部署狀態(tài)到準(zhǔn)備就緒需要 10 分鐘的時間。我在主函數(shù)的第一行設(shè)置了斷點,但它從未觸發(fā)。

我們不得不調(diào)試所有的init()函數(shù),發(fā)現(xiàn)一個隊友在一個“我不記得的包”中使用了init()函數(shù),從一個大文件加載了大量數(shù)據(jù)到內(nèi)存中,這導(dǎo)致花費了很多時間追蹤一個微小的問題。

2. 使用全局變量

這與使用單例模式時可能出現(xiàn)的問題類似,特別是當(dāng)全局變量是復(fù)雜的,包含映射、切片或指針時。

  • 競態(tài)條件(Race condition):當(dāng)使用全局變量時,多個goroutine同時訪問全局變量會導(dǎo)致意外行為。這在Go語言中是一個很大的問題。

  • 難以測試:使用全局變量會使你的項目更具狀態(tài),這意味著當(dāng)你開始單元測試/集成測試時,全局變量必須與運(yùn)行main()或生產(chǎn)環(huán)境時相同。

  • 不夠模塊化且難以重用:難以組織和封裝數(shù)據(jù),因為任何包或模塊都可以訪問它們。這可能會導(dǎo)致代碼不夠模塊化,更難以理解,因為很難確定數(shù)據(jù)來自哪里以及如何使用它們。

通常建議封裝您的包,使其可以在不影響其他包的情況下移動。使用全局變量可能會使您的代碼更緊密耦合,更難以修改或重用。

3. 忽略錯誤消息

錯誤是Go編程的內(nèi)在部分,處理它們以優(yōu)雅的方式確保在發(fā)生錯誤時不會發(fā)生意外情況非常重要。

忽略錯誤消息的方法是使用“_”符號,這樣做會丟棄函數(shù)返回的錯誤值,可能會導(dǎo)致意外行為。

檢查錯誤并適當(dāng)?shù)靥幚硭鼈円苑乐钩绦虬l(fā)生崩潰和崩潰非常重要。

// sample 1
func main() {
    var x interface{} = "hello"
    s := x.(int) // panic: interface conversion: interface {} is string, not int
    fmt.Println(s)
}
// sample 2
func main() {
    var x interface{} = "hello"
    s, _ := x.(int) // safe but DON'T
    fmt.Println(s)
}

忽略錯誤處理會導(dǎo)致生產(chǎn)代碼中出現(xiàn)重大問題,因為這可能使得識別和修復(fù)錯誤變得困難。始終檢查錯誤并適當(dāng)?shù)亟鉀Q它們對于確保代碼的順暢運(yùn)行非常重要。

4. GOTO語句 — 跳進(jìn)陷阱

不僅在Go語言中,許多語言都認(rèn)為使用“goto”語句是一種不良實踐,因為它會使代碼更難理解和維護(hù)。

原因是“goto”語句忽略了代碼流程,使得在不引入錯誤的情況下難以理解代碼的不同部分之間的依賴關(guān)系。

這可能會使得在運(yùn)行時推理程序的狀態(tài)變得困難,使得調(diào)試和測試變得更加困難。

使用“goto”可能會導(dǎo)致錯誤數(shù)量增加,使得更難以識別問題的根本原因。

5. 不使用Defer和Recover

利用“defer”和“recover”的主要原因是為了防止恐慌。“defer”甚至可以在發(fā)生恐慌時執(zhí)行,而“recover”可以捕捉到恐慌,允許更加控制地處理意外情況。

這種使用方式被認(rèn)為是不好的代碼實踐:

func readFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        panic(err)
    }
    // Do something with the file
    file.Close() // <--- DONT
}

我們使用defer這種方式,這樣即使readFile()函數(shù)出現(xiàn)panic,文件也會被關(guān)閉。此外,這樣做也容易記住在open()函數(shù)之后立即放置關(guān)閉函數(shù)。

func readFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
        log.Fatal(err)
    }
    defer file.Close()
    // Do something with the file
    ...
}

6. 使用太多次的context.Background()

在 Go 中,上下文是最強(qiáng)大的功能之一。當(dāng)正確使用時,它可以作為提供程序、樹流和流控制器。

在進(jìn)行外部調(diào)用(例如數(shù)據(jù)庫、HTTP 等)時,使用context.Background()context.ToDo()設(shè)置截止時間或超時非常重要。如果沒有設(shè)置,當(dāng)用戶過多且外部服務(wù)沒有及時響應(yīng)時,可能會導(dǎo)致您的應(yīng)用程序出現(xiàn)瓶頸。

我通常會編寫一個上下文池的實用函數(shù),其中包括 3 個函數(shù)來創(chuàng)建或包裝具有超時的新上下文:快速(0.5 秒)、中等(3 秒)、慢速(10 秒)。這樣,我就不必一直依賴context.Background(),并且可以輕松地為每個調(diào)用設(shè)置適當(dāng)?shù)某瑫r時間。

const FastTimeout = 500 * time.Millisecond
func WrapCustomContext(ctx context.Context, dur time.Duration) (context.Context, context.CancelFunc) {
    return context.WithTimeout(context.Background(), dur)
}
func GenFastContext() (context.Context, context.CancelFunc) {
    return WrapCustomContext(context.Background(), FastTimeout)
}
func WrapFastContext(ctx context.Context) (context.Context, context.CancelFunc) {
    return WrapCustomContext(ctx, FastTimeout)
}

以上就是從錯誤中學(xué)習(xí)改正Go語言壞習(xí)慣提高編程技巧的詳細(xì)內(nèi)容,更多關(guān)于Go語言編程習(xí)慣的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言中實現(xiàn)enum枚舉的方法詳解

    Go語言中實現(xiàn)enum枚舉的方法詳解

    枚舉,即?enum,可用于表示一組范圍固定的值,它能助我們寫出清晰、安全的代碼,那么你是否了解過?Go?中的枚舉呢?下面就跟隨小編一起來學(xué)習(xí)一下Go語言中實現(xiàn)enum枚舉的常用方法吧
    2024-02-02
  • Go與C語言的互操作實現(xiàn)

    Go與C語言的互操作實現(xiàn)

    在Go與C語言互操作方面,Go更是提供了強(qiáng)大的支持。尤其是在Go中使用C,你甚至可以直接在Go源文件中編寫C代碼,本文就詳細(xì)的介紹一下如何使用,感興趣的可以了解一下
    2021-12-12
  • Go簡單實現(xiàn)協(xié)程方法

    Go簡單實現(xiàn)協(xié)程方法

    本文主要介紹了Go簡單實現(xiàn)協(xié)程的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-12-12
  • Go語言中的方法定義用法分析

    Go語言中的方法定義用法分析

    這篇文章主要介紹了Go語言中的方法定義用法,實例分析了方法的定義及使用技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-02-02
  • Golang學(xué)習(xí)之map的用法詳解

    Golang學(xué)習(xí)之map的用法詳解

    在Golang(又稱Go語言)中,map是一種非常有用的數(shù)據(jù)結(jié)構(gòu),所以這篇文章小編就來帶大家一起深入了解一下map的用法,感興趣的小伙伴可以了解一下
    2023-06-06
  • go語言實現(xiàn)的memcache協(xié)議服務(wù)的方法

    go語言實現(xiàn)的memcache協(xié)議服務(wù)的方法

    這篇文章主要介紹了go語言實現(xiàn)的memcache協(xié)議服務(wù)的方法,實例分析了Go語言使用memcache的技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-03-03
  • Golang結(jié)合ip2region實現(xiàn)ip歸屬地查詢

    Golang結(jié)合ip2region實現(xiàn)ip歸屬地查詢

    ip2region - 是一個離線IP地址定位庫和IP定位數(shù)據(jù)管理框架,提供了眾多主流編程語言的 xdb 數(shù)據(jù)生成和查詢客戶端實現(xiàn),下面我們就來看看Golang如何結(jié)合ip2region實現(xiàn)ip歸屬地查詢吧
    2024-03-03
  • 詳解如何在Go語言中調(diào)用C源代碼

    詳解如何在Go語言中調(diào)用C源代碼

    這篇文章主要為大家詳細(xì)介紹了如何在Go語言中調(diào)用C語言源代碼,文中的示例代碼講解詳細(xì),對我們學(xué)習(xí)或工作有一定的幫助,需要的可以參考一下
    2022-05-05
  • 使用Go語言編寫一個極簡版的容器Container

    使用Go語言編寫一個極簡版的容器Container

    Docker作為一種流行的容器化技術(shù),對于每一個程序開發(fā)者而言都具有重要性和必要性,因為容器化相關(guān)技術(shù)的普及大大簡化了開發(fā)環(huán)境配置、更好的隔離性和更高的安全性,對于部署項目和團(tuán)隊協(xié)作而言也更加方便,本文將嘗試使用Go語言編寫一個極簡版的容器
    2023-10-10
  • golang?RPC包原理和使用詳細(xì)介紹

    golang?RPC包原理和使用詳細(xì)介紹

    golang的rpc支持三個級別的RPC:TCP、HTTP、JSONRPC。但Go的RPC包是獨一無二的RPC,它和傳統(tǒng)的RPC系統(tǒng)不同,它只支持Go開發(fā)的服務(wù)器與客戶端之間的交互,因為在內(nèi)部,它們采用了Gob來編碼
    2022-09-09

最新評論