近日,Python 被納入全國(guó)計(jì)算機(jī)等級(jí)考試科目、編入了小學(xué)教材流码、獲得了 2018 年頂級(jí)編程語(yǔ)言榮譽(yù)又官,可以說(shuō),Python 要多火就有多火漫试。而本文并非為此火上添油六敬,而是適時(shí)地為 Python 澆了一盆涼水,穩(wěn)步發(fā)展才是一門編程語(yǔ)言的正軌驾荣。本文作者使用了 Go 語(yǔ)言完成了曾經(jīng)用 Python 搞定的多種任務(wù)外构,對(duì)比發(fā)現(xiàn),Go 語(yǔ)言的方法似乎更勝一籌播掷。
其中审编,完成的任務(wù)比如說(shuō):
處理 S3 上存儲(chǔ)的 Cloudfront 日志;
在 S3 中將 TB 級(jí)別的數(shù)據(jù)從一個(gè)桶移到另一個(gè)桶歧匈,或者其他區(qū)域垒酬;
比較數(shù)據(jù)庫(kù)中的數(shù)據(jù)和 S3 中的文件,確保數(shù)據(jù)的同步件炉。
許多都是一次性的任務(wù)勘究,因此腳本語(yǔ)言很合適。程序要能很快寫出來(lái)斟冕,而且基本上用完就不會(huì)再用了口糕。通常每次任務(wù)都是全新并且唯一的,因此幾乎沒(méi)有代碼重用的可能宫静。
下面是 Go 比 Python 強(qiáng)的地方:
編譯器很好
我在 Python 中一直犯愚蠢的錯(cuò)誤走净。比如搞錯(cuò)變量名或函數(shù)名,或者給函數(shù)傳遞錯(cuò)誤的參數(shù)孤里。Devtools 能發(fā)現(xiàn)一些錯(cuò)誤伏伯,但通常這些工具需要特別設(shè)置。我從來(lái)沒(méi)能完美設(shè)置好 pylint捌袜,我也不喜歡那些需要單獨(dú)配置的笨重的 IDE说搅。
最糟糕的情況是隱藏在條件邏輯后面的錯(cuò)誤變量名。代碼會(huì)運(yùn)行幾個(gè)小時(shí)虏等,直到錯(cuò)誤觸發(fā)弄唧。然后就不得不一切從頭開始。
單元測(cè)試通常能捕獲這些錯(cuò)誤霍衫,但很難獲得 100% 的代碼覆蓋率候引,而且對(duì)于一次性的腳本我也不想浪費(fèi)時(shí)間寫測(cè)試。
編譯語(yǔ)言能完全避免這些問(wèn)題敦跌。編譯器能找出所有愚蠢的錯(cuò)誤澄干。因此,對(duì)于任何超過(guò) 100 行代碼的任務(wù),我更喜歡使用 Go麸俘。
開發(fā)速度
編譯器的缺點(diǎn)就是通常會(huì)降低開發(fā)速度辩稽。尤其在 C/C++ 和 Java 上特別明顯。
但 Go 非常簡(jiǎn)單从媚,我發(fā)現(xiàn)它對(duì)開發(fā)速度的影響非常小逞泄。不要誤會(huì),我用 Python 依然更快拜效,但用 Go 通常能達(dá)到 Python 的 85% 效率喷众。
考慮到使用編譯器能犯更少的錯(cuò)誤,85% 已經(jīng)非常值得了拂檩。
更好的并發(fā)性
你一定知道侮腹,Go 的開發(fā)目的就是并發(fā)執(zhí)行。
在我的團(tuán)隊(duì)中我們一般都需要并發(fā)編程稻励,因?yàn)槲覀円幚?S3 或數(shù)據(jù)庫(kù)中的海量數(shù)據(jù)父阻。
如果任務(wù)中有很多 IO(許多任務(wù)都是如此),那我們可以用 Python 的線程望抽。但如果需要很多 CPU加矛,那 Python 就很難辦,因?yàn)樗腥纸忉屍麈i(Global Interpreter Lock)煤篙。
而使用 Go 的多線程斟览,無(wú)需任何特殊處理就能正常工作,這一點(diǎn)非常棒辑奈。你一定體會(huì)過(guò)在 Python 中按 Ctrl-C 試圖結(jié)束多線程任務(wù)卻毫無(wú)反應(yīng)的情況吧苛茂?
更容易部署
我喜歡單一的二進(jìn)制文件。通常我在 EC2 機(jī)器上運(yùn)行代碼鸠窗,使之在網(wǎng)絡(luò)上更靠近與 S3 和數(shù)據(jù)庫(kù)妓羊。使用 Python,我需要在遠(yuǎn)程機(jī)器上安裝所有的包稍计,并確保其他人沒(méi)有安裝任何沖突的東西躁绸。
雖然 Virtualenv 能解決這個(gè)問(wèn)題,但我依然認(rèn)為 Go 更容易臣嚣。
通常我會(huì)在我的 Mac 上將代碼交叉編譯成 Linux 二進(jìn)制文件净刮,然后復(fù)制到遠(yuǎn)程機(jī)器上,然后就可以執(zhí)行了硅则。所有依賴都被放到二進(jìn)制文件中了淹父。
一致的風(fēng)格
最初,gofmt 工具的確挺煩人怎虫,特別是他們使用 tab 而不是使用空格弹灭。我認(rèn)為他們簡(jiǎn)直是瘋了督暂。
但用得多了后,我開始依賴它了穷吮。它能直接提供完美的代碼格式。不管是哪個(gè)項(xiàng)目饥努,所有代碼都有同樣的風(fēng)格捡鱼,因?yàn)轱L(fēng)格就是標(biāo)準(zhǔn) Go 工具鏈中的一部分。
而在 Python 中達(dá)到同樣的效果需要更多的功夫酷愧。必須正確配置 pylint驾诈,并保證每個(gè)項(xiàng)目的配置都是一樣的。
更好的工具鏈
gofmt 只是通用工具鏈的一個(gè)例子溶浴。所有我喜歡的編輯器乍迄,不論是 VSCode、vim 還是 SublimeText士败,都有非常好用的 Go 語(yǔ)言擴(kuò)展闯两,使用標(biāo)準(zhǔn)的 Go 工具鏈。
因此谅将,我能獲得近似 Java 的只能提示漾狼,但無(wú)需使用真正的 IDE。而使用 Python 就從來(lái)沒(méi)能享受過(guò)這樣的功能饥臂。
缺點(diǎn)
我讀到的許多批評(píng) Go 語(yǔ)言的文章都在說(shuō)它缺乏某個(gè)明顯的功能逊躁,比如泛型。但沒(méi)有泛型我也從來(lái)沒(méi)遇到過(guò)麻煩隅熙。實(shí)際上 map 和 slice 能完成許多工作稽煤。不過(guò)我卻有些其他的問(wèn)題。
Go 是有觀點(diǎn)的語(yǔ)言
首先囚戚,Go 可能是我用過(guò)的最有觀點(diǎn)(opinioned)的語(yǔ)言了酵熙。從強(qiáng)迫使用 Tab 而不是空格(假設(shè)你用 gofmt),到強(qiáng)迫使用固定的目錄格式弯淘,甚至強(qiáng)迫在GOPATH 環(huán)境變量中寫代碼绿店,許多 Go 的東西都沒(méi)辦法改變。
有觀點(diǎn)的理由之一就是這樣易于學(xué)習(xí)庐橙,因?yàn)檫@些特點(diǎn)都不會(huì)改變假勿。但如果你不想導(dǎo)出的名字以大寫字母開頭,那就沒(méi)辦法了态鳖。不過(guò)幸運(yùn)的是转培,這些問(wèn)題都不會(huì)成為我不使用 Go 的理由,但我能理解有些人無(wú)法接受浆竭。
而 Python 則更靈活浸须。
缺乏庫(kù)支持
在這個(gè)領(lǐng)域比較 Python 和 Go 并不太公平惨寿。Go 非常年輕,但我還是會(huì)在發(fā)現(xiàn) Go 本身不支持某個(gè)功能時(shí)感到很不解删窒。更讓我失望的是裂垦,一些人在 StackOverfolw 上貼了些本應(yīng)是內(nèi)置函數(shù)的代碼,然后每個(gè)人都仿佛沒(méi)事兒一樣直接把代碼粘貼到項(xiàng)目里使用肌索。
舉兩個(gè)近幾年我發(fā)現(xiàn)的例子:
對(duì) slice 排序(幸運(yùn)的是在 Go 1.8 中變得容易得多了)
math.round 只能用于整數(shù)蕉拢,而不能四舍五入成浮點(diǎn)數(shù)(比如四舍五入到最近的.5)。甚至在 Go 1.10 之前都沒(méi)有 math.round诚亚。
當(dāng)然晕换,一些原因是因?yàn)?Go 沒(méi)有泛型,一些是因?yàn)?Go 的設(shè)計(jì)思想就是只把絕對(duì)必要的東西加到標(biāo)準(zhǔn)庫(kù)中站宗。
我理解這兩個(gè)原因闸准,不過(guò)在遇到非常簡(jiǎn)單的功能卻不得不自己寫代碼時(shí)還是覺得很煩人。
希望 Go 語(yǔ)言能越來(lái)越好梢灭,痛點(diǎn)能越來(lái)越少夷家。
原文:thinkfaster.co/2018/07/goo…譯文:CSDN資訊作者:Jake Wilson譯者:彎月,責(zé)編:屠敏
CSDN學(xué)院GO語(yǔ)言課程推薦: