亚洲熟女综合色一区二区三区,亚洲精品中文字幕无码蜜桃,亚洲va欧美va日韩va成人网,亚洲av无码国产一区二区三区,亚洲精品无码久久久久久久

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

大家好,在做新的應(yīng)用選型時(shí),我們會(huì)進(jìn)行應(yīng)用編程語(yǔ)言的選擇,這時(shí)會(huì)糾結(jié) Java、PHP、Go...各種,會(huì)思考有沒(méi)有致命的問(wèn)題,不能用?

可以明確的是,Go 沒(méi)有非常致命的問(wèn)題,否則你我他都不會(huì)在這里相遇,也不會(huì)大火。

難受的點(diǎn),倒是有不少,今天就和大家一起來(lái)看看。

難受的點(diǎn)

泛型

在 Go1.18 以前,在所有社交媒體和調(diào)查報(bào)告上來(lái)看。Go 最難受的莫過(guò)于沒(méi)有泛型,

寫一個(gè)通用的方法,要不得把入?yún)⒙暶鳛?interface,要不得寫 N 個(gè)不同類型的一樣代碼的函數(shù),代碼重復(fù)率高。

如下圖:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

這是 Go1.18 以前最難受的點(diǎn),現(xiàn)在新版本雖然有了泛型,但現(xiàn)階段配套標(biāo)準(zhǔn)和開源庫(kù)還沒(méi)完全到位,影響還是會(huì)繼續(xù)存在。

淺拷貝和泄露

在寫 Go 程序時(shí),我們經(jīng)常要用到 slice、map 等基礎(chǔ)類型。但有一個(gè)比較麻煩的點(diǎn),就是會(huì)涉及到淺拷貝。

一個(gè)不注意就會(huì)引起 BUG,如下代碼:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

輸出結(jié)果是什么?

煎魚到底是上班了,還是下班了?

結(jié)果如下:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

實(shí)際上在?y := x?時(shí),他拷貝的是指向?qū)ο蟮闹羔槪@個(gè)時(shí)候?x?和?y?的底層數(shù)據(jù)其實(shí)是一家子,自然一變動(dòng)?y,x?的煎魚也就下班了。

同類型的 slice 也有 append 的泄露,以及 len、cap 的不準(zhǔn)確問(wèn)題,是比較折騰人的。

泄露的示例:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

錯(cuò)誤處理

在 Go 的錯(cuò)誤處理中,許多小伙伴的難受的點(diǎn)分兩大塊。一個(gè)是大量重復(fù)的?if err != nil?的代碼:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

另外一塊是在異常處理中,Go 現(xiàn)階段是 panic 和 recover 的模式,內(nèi)部還包含 throw 的致命性錯(cuò)誤拋出,無(wú)法攔截,為此我也見(jiàn)過(guò)個(gè)別事故是因此造成的。

這是一個(gè)爭(zhēng)議性很大的板塊。

nil 接口不是 nil

我們強(qiáng)行將一段 Go 程序的變量值賦為 nil,并進(jìn)行 nil 與 nil 的判斷。

代碼如下:

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

輸出的結(jié)果是什么。是 false,還是 true,又或是拋出異常?

輸出結(jié)果是?fasle,nil 可不 100% 等于 nil。

這與 interface 的內(nèi)部數(shù)據(jù)結(jié)構(gòu)有關(guān),是在編程時(shí)要注意的一個(gè)細(xì)節(jié)。

垃圾回收

Go 非常簡(jiǎn)潔,垃圾回收唯一的可調(diào)節(jié)的是 GC 頻率,可以通過(guò) GOGC 變量設(shè)置初始垃圾收集器的目標(biāo)百分比值。

為什么 Go 用起來(lái)會(huì)難受?這 6 個(gè)細(xì)節(jié)你知道嗎

簡(jiǎn)單來(lái)講就是,GOGC 的值設(shè)置的越大,GC 的頻率越低,但每次最終所觸發(fā)到 GC 的堆內(nèi)存也會(huì)更大。

然后就沒(méi)別的方式可以優(yōu)化垃圾回收器本身了,以至于當(dāng)年我還被人拿 Java 來(lái)吐槽過(guò)一遍,說(shuō) Go 肯定有。

依賴管理

壓軸的難受點(diǎn),莫過(guò)于 Go 的依賴管理。先是從 GOPATH 時(shí)代,開源后一路水土不服,后面 rsc 直接下場(chǎng)支棱起來(lái)硬推。

到 2022 年,目前 Go modules 還是會(huì)存在一些讓人難受的點(diǎn)。甚至曹大總結(jié)了 《Go mod 七宗罪》,不少我在工作中也遇到和替別人解決過(guò),非常的精辟。

引用曹大文章中的 7 點(diǎn):

  • Go 命令的副作用:所有 go build、go list、go test 多多少少都會(huì)拉取到墻外的資源,會(huì)很慢。
  • 形同虛設(shè)的 semver 規(guī)范:go mod 的設(shè)計(jì),就是希望大家在軟件庫(kù)發(fā)布時(shí)都要遵守標(biāo)準(zhǔn),例如在小版本時(shí),要保持兼容性。但這非常理想化,現(xiàn)實(shí)就是經(jīng)常有人不遵守。
  • 無(wú)法應(yīng)對(duì)刪庫(kù):發(fā)布后的軟件庫(kù),你已經(jīng)拉取了。但發(fā)布者依然可以刪除,受傷的還是自己。
  • goproxy 的實(shí)現(xiàn)并不統(tǒng)一:作者 A、作者 B、作者 C 寫的幾套 goproxy 內(nèi)部邏輯是不完全一致的,很折騰人。
  • go get 到的 lib 版本在 go build 時(shí)被修改。
  • 版本信息擴(kuò)散:導(dǎo)入路徑是包含版本號(hào) v1、v2 等信息的,一旦修改,就得大面積替換。
  • go.sum 合并沖突:大型項(xiàng)目上的多人維護(hù),導(dǎo)致頻繁沖突。

熟悉掌握 Go 的一個(gè)表現(xiàn),那就是精通 Go modules,不然項(xiàng)目都運(yùn)行的不順利。

總結(jié)

今天我們圍繞 Go 的難受場(chǎng)景進(jìn)行了分析和講解,本文涉及的分別是:泛型、淺拷貝和泄露、錯(cuò)誤處理、nil 接口不是 nil、垃圾回收、依賴管理。

其中不少是常見(jiàn)的,也有的是有意而為之(例如:垃圾回收)。從大家的角度來(lái)看,你覺(jué)得 Go 比較難受的點(diǎn)還有哪些呢?

歡迎大家在評(píng)論區(qū)一起留言和交流。

原文:https://mp.weixin.qq.com/s/8ino57_pYncjotquaCt3dw,侵刪

相關(guān)新聞

歷經(jīng)多年發(fā)展,已成為國(guó)內(nèi)好評(píng)如潮的Linux云計(jì)算運(yùn)維、SRE、Devops、網(wǎng)絡(luò)安全、云原生、Go、Python開發(fā)專業(yè)人才培訓(xùn)機(jī)構(gòu)!