日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當前位置:首頁 > 科技  > 軟件

從錯誤中學習:了解 Go 編程的六個壞習慣

來源: 責編: 時間:2024-01-08 09:16:12 205觀看
導讀使用Go和使用其他編程語言中一樣,需要了解常見錯誤和不良實踐,才能編寫既干凈又高效的代碼。本文討論的一些實踐并不一定都是不好的,在特定情況下很有用。 然而,我們需要知道可能會有什么問題,為什么應該回避某些習慣,以及

使用Go和使用其他編程語言中一樣,需要了解常見錯誤和不良實踐,才能編寫既干凈又高效的代碼。eTN28資訊網——每日最新資訊28at.com

本文討論的一些實踐并不一定都是不好的,在特定情況下很有用。 然而,我們需要知道可能會有什么問題,為什么應該回避某些習慣,以及如何避開常見的陷阱。eTN28資訊網——每日最新資訊28at.com

eTN28資訊網——每日最新資訊28at.com

1. 使用init()

Go中的init()函數是一個特殊函數,在main函數之前執行。eTN28資訊網——每日最新資訊28at.com

"如果初始化對于任何包都很重要,為什么init()在Go中被認為是一個不好的做法?"eTN28資訊網——每日最新資訊28at.com

eTN28資訊網——每日最新資訊28at.com

是的,雖然init()函數確實有助于在運行核心邏輯之前進行初始化,但其執行順序可能很難理解,可能導致對初始化順序的混淆。eTN28資訊網——每日最新資訊28at.com

// package Afunc init() {}// package B func init() {}// which run first?

想象一下,有兩個模塊在安裝時相互依賴,但位于不同的包中。結果我們最終需要編寫更復雜的代碼來管理時序,更糟的是,甚至可能陷入死鎖情況。eTN28資訊網——每日最新資訊28at.com

使用init()的另一個缺點是測試會變得復雜。因為這些函數是自動運行的,無法選擇何時執行。eTN28資訊網——每日最新資訊28at.com

缺乏控制使得設置測試用例成為一項挑戰。eTN28資訊網——每日最新資訊28at.com

我曾經遇到過一個問題,我的服務在部署后花了很長時間才準備好。我在main()函數的開始處設置了一個斷點,但從未觸發。eTN28資訊網——每日最新資訊28at.com

eTN28資訊網——每日最新資訊28at.com


eTN28資訊網——每日最新資訊28at.com

經過冗長的調試后,我們發現一個成員使用了某個包中的init()函數從一個大文件加載一個大數據集,這讓我們花費大量時間去解決這么一個小問題。eTN28資訊網——每日最新資訊28at.com

2. 使用全局變量

Go中的全局變量可能會帶來類似單例的問題,特別是當這些全局變量很復雜時(比如映射、切片或指針)。eTN28資訊網——每日最新資訊28at.com

"那么,全局變量有什么大不了的?"eTN28資訊網——每日最新資訊28at.com

eTN28資訊網——每日最新資訊28at.com

  • 競爭條件: 當有多個程序試圖同時訪問同一個全局變量時,事情可能會變得混亂。
  • 更少的可測試性: 應用程序依賴于全局變量,意味著有狀態,從而在單元或集成測試期間,這些全局變量需要與main()函數中的內容或在生產環境中部署的內容保持一致。
  • 模塊化程度較低,可重用性較差: 可以從任何地方訪問全局變量,很難跟蹤其使用方式和位置。

因此,這里的建議是保持對包的封裝。eTN28資訊網——每日最新資訊28at.com

從而使得代碼更容易移動,并且不太可能破壞其他東西。通過避免使用全局變量,可以使代碼不那么受約束,并且更容易更新或復用。eTN28資訊網——每日最新資訊28at.com

3. 忽略錯誤信息

用Go編程時,錯誤是不可避免的,知道如何處理錯誤可以讓我們避免各種各樣的問題。eTN28資訊網——每日最新資訊28at.com

"忽略錯誤真的那么糟糕嗎?"eTN28資訊網——每日最新資訊28at.com

eTN28資訊網——每日最新資訊28at.com

是的,完全正確。eTN28資訊網——每日最新資訊28at.com

一些Go新手可能會用"_"符號將錯誤撇在一邊,但忽略函數返回的錯誤值,可能會帶來麻煩。eTN28資訊網——每日最新資訊28at.com

如果不對錯誤進行管理,也許程序會出現panic和crash。eTN28資訊網——每日最新資訊28at.com

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

跳過錯誤可能會適得其反,尤其是對于線上生產環境,調試會成為一場噩夢??偸?-我的意思是總是--檢查錯誤并采取正確的措施以保持代碼順利運行。eTN28資訊網——每日最新資訊28at.com

4. 避免GOTO

無論用Go還是其他語言,避免使用"goto"是大家的共識。eTN28資訊網——每日最新資訊28at.com

使用goto會破壞代碼的自然流程。eTN28資訊網——每日最新資訊28at.com

會破壞我們理解不同代碼段之間關系的方式,讓我們很難在不弄得亂七八糟的情況下修改代碼。eTN28資訊網——每日最新資訊28at.com

此外,調試也變得更加令人困惑,測試也更加棘手。eTN28資訊網——每日最新資訊28at.com

從本質上講,依賴goto往往會產生更多錯誤,并難以深入了解問題。因此,作為最佳實踐,明智的做法是避開它。eTN28資訊網——每日最新資訊28at.com

5. 跳過Defer和Recover

如果你忽略"defer"和"recover",就失去了對panic的堅實保護。eTN28資訊網——每日最新資訊28at.com

為什么?eTN28資訊網——每日最新資訊28at.com

因為當出現panic時,"defer"仍然會起作用,而"recover"會抓住panic,讓我們有機會處理不可預見的問題[2]。eTN28資訊網——每日最新資訊28at.com

看看這個例子,其中'file.Close()'只是放在末尾,這不是一個Go風格的解決方案:eTN28資訊網——每日最新資訊28at.com

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

相反,像這樣使用"defer":eTN28資訊網——每日最新資訊28at.com

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

在打開文件后立即調用defer file.Close()可以確保即使readFile()遇到panic,文件也會被關閉。此外,還可以方便的提醒我們在打開資源后立即進行清理。eTN28資訊網——每日最新資訊28at.com

6. 過多使用context.Background()

Go的context功能非常有用,當代碼與數據庫或網站對話時,有助于管理時間限制等事情。eTN28資訊網——每日最新資訊28at.com

如果沒有設定截止時間,應用可能會陷入阻塞,被數以百萬計的請求淹沒。eTN28資訊網——每日最新資訊28at.com

通過一個特殊功能,可以很容易的設置時間限制。eTN28資訊網——每日最新資訊28at.com

該函數有三種時間選擇: Fast(0.5秒)、Medium(3秒)和Slow(10秒)。這樣就不用一直使用context.Background(),而且可以為每個任務選擇合適的時間限制。eTN28資訊網——每日最新資訊28at.com

以下是Fast的一些示例代碼:eTN28資訊網——每日最新資訊28at.com

const FastTimeout = 500 * time.Millisecondfunc WrapCustomContext(ctx context.Context, dur time.Duration) (context.Context, context.CancelFunc) {  return context.WithTimeout(ctx, 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)}

有了這些函數,就可以選擇正確的時間限制,應用也因此運行得更好。eTN28資訊網——每日最新資訊28at.com

好還是不好,只是一些概念,我們可以決定其真正含義。eTN28資訊網——每日最新資訊28at.com

所以,明智的使用"不好"的特性,它就能變成"最好"的方案。eTN28資訊網——每日最新資訊28at.com

參考資料:eTN28資訊網——每日最新資訊28at.com

  • [1]5+ BAD Practices In Go: Learn From Mistakes: https://levelup.gitconnected.com/5-bad-practices-in-go-learn-from-mistakes-13afb4d303b3
  • [2]What you know about defer in Go is not enough!: https://medium.com/@func25/what-you-know-about-defer-in-go-is-not-enough-2681d4b128c3

本文鏈接:http://www.www897cc.com/showinfo-26-57886-0.html從錯誤中學習:了解 Go 編程的六個壞習慣

聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: C++控制臺彩色時鐘的實現

下一篇: 什么是Helm?它是如何提升云原生應用私有化部署效率的

標簽:
  • 熱門焦點
  • 影音體驗是真的強 簡單聊聊iQOO Pad

    大公司的好處就是產品線豐富,非常細分化的東西也能給你做出來,例如早先我們看到了新的vivo Pad2,之后我們又在iQOO Neo8 Pro的發布會上看到了iQOO的首款平板產品iQOO Pad。雖
  • 如何使用JavaScript創建一只圖像放大鏡?

    譯者 | 布加迪審校 | 重樓如果您曾經瀏覽過購物網站,可能遇到過圖像放大功能。它可以讓您放大圖像的特定區域,以便瀏覽。結合這個小小的重要功能可以大大改善您網站的用戶體驗
  • 一個注解實現接口冪等,這樣才優雅!

    場景碼猿慢病云管理系統中其實高并發的場景不是很多,沒有必要每個接口都去考慮并發高的場景,比如添加住院患者的這個接口,具體的業務代碼就不貼了,業務偽代碼如下:圖片上述代碼有
  • 使用AIGC工具提升安全工作效率

    在日常工作中,安全人員可能會涉及各種各樣的安全任務,包括但不限于:開發某些安全工具的插件,滿足自己特定的安全需求;自定義github搜索工具,快速查找所需的安全資料、漏洞poc、exp
  • 10天營收超1億美元,《星鐵》比《原神》差在哪?

    來源:伯虎財經作者:陳平安即便你沒玩過《原神》,你一定聽說過的它的大名。恨它的人把《原神》開服那天稱作是中國游戲史上最黑暗的一天,有粉絲因為索尼在PS平臺上線《原神》,怒而
  • 東方甄選單飛:有些鳥注定是關不住的

    作者:彭寬鴻來源:華爾街科技眼&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;&zwj;東方甄選創始人俞敏洪帶隊的&ldquo;7天甘肅行&rdquo;直播活動已在近日順利收官。成立后一
  • OPPO、vivo、小米等國內廠商Q2在印度智能手機市場份額依舊高達55%

    7月20日消息,據外媒報道,研究機構的報告顯示,在全球智能手機出貨量同比仍在下滑的大背景下,印度這一有潛力的市場也未能幸免,出貨量同比也有下滑,多家廠
  • 2299元起!iQOO Pad開啟預售:性能最強天璣平板

    5月23日,iQOO如期舉行了新品發布會,除了首發安卓最強旗艦處理器的iQOO Neo8系列新機外,還在發布會上推出了旗下首款平板電腦——iQOO Pad,其搭載了天璣
  • iQOO Neo8 Pro評測:旗艦雙芯加持 最強性能游戲旗艦

    【Techweb評測】去年10月,iQOO推出了一款Neo7手機,該機搭載了聯發科天璣9000+,配備獨顯芯片Pro+,帶來了同價位段最佳的游戲體驗,一經上市便受到了諸多用
Top 主站蜘蛛池模板: 寿宁县| 静安区| 咸丰县| 兴义市| 兰坪| 富阳市| 甘南县| 松桃| 拉孜县| 乐至县| 韶山市| 古交市| 南郑县| 枣阳市| 定兴县| 乃东县| 固阳县| 辛集市| 乐安县| 临洮县| 江阴市| 蒙山县| 天峻县| 铁岭县| 黄平县| 盘山县| 桐城市| 平远县| 金沙县| 乐亭县| 新平| 资中县| 城口县| 岳池县| 茌平县| 睢宁县| 礼泉县| 贺州市| 定兴县| 黎川县| 九寨沟县|