為什麼 Go 語言能在中國這麼火?

概述

Go語言是Google開發的一種靜態強類型、編譯型、併發型,並具有垃圾回收功能的編程語言,它用批判吸收的眼光,融合C語言、Java等眾家之長,將簡潔、高效演繹得淋漓盡致。

Go語言起源於2007年,當時Google的技術大神們備受C++越來越臃腫的困擾,決心開發一種新的語言來取代C++。他們認為:與其在臃腫的語言上不斷增加新的特性,不如簡化編程語言。於是,Golang這門新語言應運而生。

在十年多的時間裡,Go語言發展勢頭強勁,憑藉其簡潔、高效的特性,在競爭激烈的編程語言市場中佔據了一席之地。Google、騰訊、阿里等大公司紛紛選擇使用Go語言來開發服務應用項目。當然,和其他的編程語言一樣,Go語言也有其自身的缺陷。

為什麼 Go 語言能在中國這麼火?

特點及優勢

Go語言的設計者們一直致力於降低構建簡單、可靠、高效軟件的門檻。相比於其他語言,Go語言具有眾多令人興奮不已的特點和優勢:

1.自動垃圾回收降低了開發難度

內存和資源管理一直是一個讓人非常抓狂的難題。在其他語言(如C或C++)中,使用內存前要先分配這段內存,使用完畢後再將其釋放掉,一個小疏忽就可能引發內存洩漏,導致程序甚至系統崩潰。而Go語言的現代化垃圾回收機制顯著地降低了開發難度,把無趣的內存管理交給專業的編譯器去做,而讓程序員專注於更有趣的事情。

2.更豐富的內置類型

Go語言是一種典型的實戰派語言,它內置了一個其他靜態語言通常用庫方式來支持的字典類型(map),理由很簡單:既然絕大多數開發者都需要用到這個類型,為什麼還非要每個人都寫一行import語句來包含一個庫?

Go語言還新增了一個數據類型:數組切片(Slice)。我們可以將數組切片看作是一種可動態增長的數組,其功能與C++標準庫中的vector類似,但有效地消除了反覆寫以下幾行代碼的工作量:

#include <vector>#include#include<algorithm>
using namespace std;
/<algorithm>
/<vector>

使用Go語言,開發者不用再費事添加依賴的包,既減少了輸入工作量,又可以讓代碼更簡潔。

3.支持函數多返回值

目前的主流語言中除Python外基本都不支持函數的多返回值功能,但很多情況下開發者非常需要這個功能。比如,我們要定義一個函數,用於返回個人的名字信息,而名字信息包含多個部分——姓氏、名字、中間字,在不支持多返回值的語言中有兩種做法來實現名字信息的返回:

專門定義一個結構體:

struct name
{
char first_name[20];
char middle_name[20];
char last_name[20];
};
extern name get_name();//函數原型
name n = get_name();//函數調用

或以傳出參數的方式返回:

extern void get_name( 

char* first_name,
char* middle_name,
char* last_name);//函數原型
//先分配內存
char first_name[20];
char middle_name[20];
char last_name[20];
//函數調用
get_name(first_name,middle_name,last_name);

Go語言的多返回值功能讓開發者既不用再只為了返回多個值而專門定義一個數據結構,也不用再區分參數列表中哪幾個用於輸入,哪幾個用於輸出。

使用Go語言返回名字信息可以這樣寫:

func getName(firstName,middleName,lastName string){
return "May","M","Chen"
}
fn,mn,ln,nn := getName()//函數調用

4.漂亮的錯誤處理

漂亮的錯誤處理規範是Go語言最大的亮點之一。Go語言引入了defer關鍵字用於標準的錯誤處理流程,並提供了內置函數panic、recover完成異常的拋出與捕獲。與C++和Java等語言中的異常捕獲機制相比,Go語言的錯誤處理機制可以大量減少代碼量,開發者無需再僅為了程序安全而添加大量一層套一層的try-catch語句。

5.匿名函數和閉包

在Go語言中,所有的函數也是值類型,可以作為參數傳遞。Go語言支持常規的匿名函數和閉包,比如下列代碼就定義了一個名為f的匿名函數,開發者可以隨意對該匿名函數變量進行傳遞和調用:

f := func(x,y,int) int{
return x+y
}

6.簡潔的類型和“非侵入式”接口

Go語言的類型定義非常接近C語言中的結構(struct),甚至直接沿用了struct關鍵字。為了保持簡潔,Go語言沒有直接沿襲C++和Java的傳統去設計一個超級複雜的類型系統,不支持繼承和重載,而只是支持最基本的類型組合功能。雖然看起來過於簡潔,但Go語言依然能夠實現C++和Java使用複雜的類型系統才能實現的功能。

而引入強大的“非侵入式”接口讓開發者從以往對C++和Java開發中的接口管理問題中解脫了出來。

7.併發編程更輕盈更安全

Go語言引入了goroutine概念。goroutine是一種比線程更加輕盈、更省資源的協程。通過使用goroutine而不是裸用操作系統的併發機制,以及使用消息傳遞來共享內存而不是使用共享內存來通信,併發編程變得更加輕盈和安全。

主要應用場景

Golang非常適合用來做網絡併發方面的服務,比如消息推送、監控、容器等。國內外的很多著名公司都使用了Go語言來開發服務及應用,比如:

  • Google最核心的搜索和廣告業務;
  • 騰訊的Docker容器化
  • 百度的運維BFE(Baidu Front End)項目,應對龐大的前端頁面訪問量。
  • 小米的運維監控系統,小米商城、小米視頻等團隊也在使用Go語言

不足之處

儘管Go語言獨特的垃圾回收機制和併發編程機制等設計使代碼更簡潔,並大大提高了程序的性能,但與Python、Java、C/C++等語言相比,Go語言還是太年輕。

1.軟件包版本管理不完善

Go語言的軟件包版本管理一直被開發人員吐槽。Go語言沒有制定特定版本的依賴庫,在不同時間構建時,創建的生成可能會基於不同版本的包。在這方面,Go語言還無法與Python、Java等語言的軟件包管理系統相媲美。

2.錯誤信息難獲得

Go語言的錯誤處理最被人所詬病的一點是,開發者不能從函數上知道下層函數可能返回哪些類型的錯誤,很容易丟失錯誤發生的範圍,難以提供有效的錯誤信息。

作為一門新興的語言,Go語言難免存在種種缺陷。但出身名門的它擁有強大的後備力量,開源社區的用戶不斷地貢獻新的輪子,Google也組建了一個獨立的小組全職開發Go語言,在Google內部,Go語言有逐漸取代Java和Python主流地位的趨勢。未來Go語言的身影應該會出現在越來越多的應用服務當中。

對大多數公司來說Golang的主要優勢是和C++比有GC,和Java比更簡潔,和Python比更快,這就在一個不錯的位置上了,沒有明顯的短板。以大部分程序員的水平而言,Golang的缺點還還沒有到能對他們產生困擾的程度,他們自己給自己造成的麻煩比語言給他們帶來的麻煩多得多。

有的公司和程序員是被舊的語言逼瘋了,C++老是內存洩漏或者crash,Java老是變成一大坨,Python老是重構火葬場,就覺得,我換個新語言,這些問題肯定都能解決了。而且往往換完發現的確有很大改善。

為什麼 Go 語言能在中國這麼火?

但我不得不潑一盆冷水:沒用的,真的沒用。

垃圾代碼的產生永遠是因為垃圾程序員,而不是垃圾語言。語言可以很垃圾,但歸根結底,垃圾語言只是阻礙你寫出好代碼,而自由奔放地寫出垃圾代碼的鍋必須全部扣在程序員的頭上。

真的把Golang用好的程序員不多,大部分人寫什麼語言都是差不多的,並不會深入思考Golang的語言模型與其他語言有什麼區別,goroutine、channel怎麼用才更合理這些問題,以前用線程池,就搞個goroutine池;以前用隊列,就去找個隊列庫。還有的乾脆全局變量滿天飛,goroutine結果全收集到全局變量裡,加個大鎖。這樣的代碼會有效率嗎?會好維護嗎?會簡潔嗎?

的確,在你剛剛換到這門語言的時候,你會發現之前你之前代碼的那些問題全都沒有了,感覺前途一片光明。遺憾的是,這是因為你僅僅才開始寫了幾個模塊,還沒有進入維護期。如果你保持著之前的水準,那些往日的惡習會讓你的代碼再次劣化,讓往日的問題再度暴露出來。然後你會想,原來Golang也有這麼多的毛病啊,也許我應該重新換成Java?然後再重複一遍這個歷史。

不深入去鑽研軟件工程的規律和技術,不深入去學習一門語言的獨有特色,理解語言的設計哲學,建立語言的一套使用方法論,僅僅妄想通過換一門新語言就解決問題,這是一條死路。許多忙著轉Golang的程序員給我的感覺都是太浮躁,這樣的狀態很容易生產出新一批通往火葬場的垃圾代碼,只要走著瞧罷了。反過來,如果借這個機會去深入學習如何寫出優秀的Golang代碼,不失為職業生涯的一個重大轉機,很快我們也能知道這麼做了的人有哪些的。

為什麼 Go 語言能在中國這麼火?

go語言學習資料獲取方式:轉發文章+關注私信【資料】


分享到:


相關文章: