如題,為啥選用Go
語言?
本文將介紹該語言誕生的原因,核心特性以及應用場景等。
Go語言
為什麼一會叫Go,一會又叫Golang?
這是因為Go的全名為Go language
,簡稱可以為Golang或者Go。而Go表示的意思有太多了,比如在英文裡表示很多意思,很難讓人們想到程式語言,所以一般在搜尋時可以以Golang
作為關鍵字。但是在這篇文章裡,兩者等價的,所以有時可能稱為Go,有時是Golang。
Google在創造Go的原因:
這裡摘選一個GitHub倉庫
最近十年來,C/C++在計算領域沒有很好得到發展,並沒有新的系統程式語言出現。對開發程度和系統效率在很多情況下不能兼得。要麼執行效率高,但低效的開發和編譯,如C++;要麼執行低效,但擁有有效的編譯,如.NET、Java;所以需要一種擁有較高效的執行速度、編譯速度和開發速度的程式語言,Go就橫空出世了。
傳統的語言比如c++,大家花費太多時間來學習如何使用這門語言,而不是如何更好的表達寫作者的思想,
同時編譯花費的時間實在太長,對於編寫-編譯-執行這個鏈條來說週期太長。動態語言如Python,
由於沒有強型別的約束,很多問題需要在執行時發現,這種低階錯誤更應該交給編譯器來發現。
執行效率 execution speed:
C/C++ > Java > PHP 開發效率 developing efficiency: PHP > Java > C/C++
簡單一句話,為了兼顧執行速度與開發效率。可以看成Go=C+python。
因為它本質上是個靜態語言,不過編譯器給了開發者許多「語法糖」,所以又兼備動態語言的特點。
並行程式設計:這個我覺得是最重要的特點,人家天然就支援並行。誒,有朋友可能會講了,Java不也支援並行嗎?Java是支援,它還有個關鍵字synchronized
可以解決並行中的共用變數問題呢!但是人家底層還要涉及到核心層面的開銷,所以一些鎖特別「重」。而Go和它相比開銷就小的多。
不僅如此,還有個重要的點,人家是多執行緒。Go是多攜程程式設計。什麼是攜程。攜程可以理解為更加輕量的執行緒(gorountine),可以高效的處理並行,更加高效地利用多核。 一次可以在程式中啟動成千上萬個gorountine,從而高效地完成任務。
而gorountine之間的通訊採用獨特的chanel機制,確保gorountine之間可以通訊。
記憶體回收(gc):這個大家就比較熟悉了,學過Java的朋友不陌生。我們在開發程式時無須去考慮記憶體問題,因為有jvm會幫我們自動釋放記憶體。而Go也同理,它會幫我們自動回收。
GC過程:先stop the world,掃描所有物件判活,把可回收物件在一段bitmap區中標記下來,接著立即start the world,恢復服務,同時啟動一個專門的goroutine,回收記憶體到空閒list中以備複用,不物理釋放,物理釋放由專門執行緒定期來執行。GC瓶頸在於每次都要掃描所有物件來判活。待收集的物件數目越多,速度越慢。GC效能可能會隨著版本不斷更新會不斷優化。只需要new分配記憶體,不需要釋放。
這裡插播一下,關於Go的記憶體分配。
在初始化階段直接分配一塊大記憶體區域,大記憶體被切分成各個大小等級的塊,放入不同的空閒list中。物件分配空間時從空閒list中取出大小合適的記憶體塊。記憶體回收時,會把不用的記憶體重放回空閒list。空閒記憶體會按照一定策略合併,以減少碎片。
網路程式設計:這裡說白了就是像其它語言一樣,也提供了豐富便捷的網路程式設計介面。Go語言還自帶了高效能的HttpServer,通過簡單的幾行程式碼呼叫,就可以得到一個基於協程的高效能Web服務,維護成本極低,沒有任何依賴。
socket用net.Dial(基於tcp/udp,封裝了傳統的connect、listen、accept等介面);
http用http.Get/Post();
rpc用client.Call(‘class_name.method_name’, args, &reply);
函數多返回值:不僅返回本來的值,還可以返回一個error物件,用來出現異常時使用。這也是Go推薦的程式設計風格。有時候會有這種需求。
語言互動性:可以呼叫其它語言編譯之後的庫,比如C。
例外處理:Go語言不支援try catch這樣的結構化的異常解決方式。Go語言提供的例外處理方式是:如果是普通異常,檢視被呼叫方返回的error物件;如果是嚴重異常,指的是中斷性panic(比如除0),使用defer…recover…panic機制來捕獲處理。嚴重異常一般由Go語言內部自動丟擲,不需要使用者主動丟擲,避免傳統try…catch寫得到處都是的情況。
三個重要關鍵字defer、panic、recover;
defer是函數結束後執行,呈先進後出;
panic是程式出現無法修復的錯誤時使用,但會讓defer執行完;
recover會修復錯誤,不至於程式終止。當不確定函數不會出錯時使用defer+recover。
除此之外還有一些其它的特性了,比如上文也出現的defer機制,本質上是延遲執行。個人覺得有點像Java中的finally和守護執行緒。還有一些型別推導等特性,各位在具體學習中會感受到,這裡不多介紹了。
主流的應用場景有那麼幾個:
不僅如此,Golang還被用來開發一些中介軟體。比如大名鼎鼎的docker
、k8s
等。人家就是用Golang來做的。還有微服務註冊中心consul
等等。
之前在網上看到一個總結,未來的軟體系統應用可能是C/C++負責底層實現,Java負責高層(即業務層)的編碼實現,而Go可以來負責中間層的實現。目前來看的確有這種趨勢。
但是和其它語言相比,個人還是覺得Go的特性雖然足夠誘人,但是國內的社群活躍度還是不夠,這裡也希望各位學習該語言的小夥伴可以一塊記錄下部落格或貢獻開原始碼,一起為這個社群貢獻出一份力。
文中有些內容摘選自網際網路。最後,感謝您的觀看🙏