剛開始接觸Go語言,看了兩本Go語言的書,從c++開發者的角度來看看go語言的新特性,說下本身感觸較深的幾點:python
Go語言層面支持協程,將併發業務邏輯從異步轉爲同步,大幅提升開發效率;
在c++中,作併發編程目前主流的方案是事件驅動(單線程/多線程/多進程模型等),而事件驅動就須要一個IO多路複用的分發器(select/epoll),這樣,就形成了業務邏輯的斷開,在代碼層面爲異步模型,好比:
1).先是一段業務代碼
2).調用IO(業務斷裂)
3).IO完成後的後續處理邏輯;
而go中的協程的支持讓這樣的開發工做就輕鬆多了,按照同步的方式順序寫業務邏輯,遇到IO也不要緊,一個線程中能夠建立成上百萬個協程,這個協程阻塞了就跑下一個,不須要應用代碼層面來負責IO後續調度的處理;
比起本身用C/C++去封裝底層或調用libevent之類的庫,Go的優點是將事件機制封裝成了CSP模式,編程變得方便了,可是須要付出goroutine調度的開銷;
ps1:Go語言標準庫提供的全部系統調用操做(固然也包括全部同步IO 操做),都會出讓CPU 給其餘goroutine;
ps2:看過網上的經驗數據,同步和異步的開發效率(不是運行效率,指的是出活速度)差很少是4:1,嘿嘿,這個數據好激動~~
關於事件驅動與協程在處理併發上的對比,詳見不鳥萬Rio的回答:
https://www.zhihu.com/question/19585576/answer/12424447c++
毫無疑問這個好用,有了垃圾回收,不須要開發者自行控制內存的釋放,這樣可避免一堆問題(重複釋放、忘記釋放內存、訪問已釋放的內存等);
固然,c++11引入的智能指針(unique_ptr等)若是在程序中應用的廣泛,也能夠達到相似垃圾回收的目的;
GC帶來的問題也是有的,會形成STW,會有程序中止調度的卡頓;
Go1.5的GC利用各類手段大大縮減了STW的時間。Go語言官方保證,在50毫秒的Go程序運行時間中因GC致使的調度停頓至多隻有10毫秒。
(ref:http://www.infoq.com/cn/articles/2015-review-go)git
這在python裏算不得什麼新鮮事,但對c++來講,要實現函數返回多個數據,要麼封裝一個結構體,要不就只能經過函數傳參實現;
多返回值這玩意,在碼字的時候能提高心情愉悅感啊,想一想,在要返回多個值的場景,不用再找個地方用一個結構體封裝一下,直接返回,多直接:
func getName()(firstName, middleName, lastName, nickName string){
return "May", "M", "Chen", "Babe"
}程序員
提到多返回值,就接着說說錯誤處理,估計多返回值應用最多的場景就是第二個參數傳回函數的錯誤狀態;好比如下寫法就很常見了:
if result, ok := moreMagic(); ok {
/ Do something with result /
}
c/c++對錯誤的處理通常都是經過錯誤碼來肯定一個函數是否正確調用,所以相比c/c++而言,go的錯誤處理代碼行減小了,看上去也美觀優雅;
go引入了3個關鍵字(defer、panic和
recover)用於標準的錯誤處理流程;defer關鍵字的引入,保證錯誤處理的代碼在發現錯誤時必定可以被調用,不會由於業務分支邏輯上的修改而漏調;github
固然,看和誰比了,python的實踐者認爲沒有使用try catch的異常處理機制,讓錯誤處理顯得很繁瑣;
Russ Cox指出Go語言是爲大型軟件設計的,Go語言的返回錯誤方式,不能否認,對於調用者不是很方便,但這樣作會讓程序中可能會出錯的地方顯的很明顯。對於小程序來講,你可能只想打印出錯誤,退出程序。對於一些很精密的程序,根據異常的不一樣,來源的不一樣,程序會作出不一樣的反應,這很常見,這種狀況中,try + catch的方式相對於錯誤返回模式顯得冗長。
ref:
Go語言的錯誤處理機制引起爭議
http://www.infoq.com/cn/news/2012/11/go-error-handle編程
函數做爲「類型」出現,成爲了一等公民;能夠定義函數類型,將一個函數賦值給函數變量,而後在業務鏈中傳遞,這個在c++中只有使用std::function才能作到;
還可使用匿名函數(對應c++11中的lambda表達式),在語言層面支持函數編程,從而能夠對程序進行更加靈活的控制和管理。小程序
系統作大作久了,代碼質量不免降低;開發人員的代碼風格不一致,致使程序中充斥着千奇百怪的命名及類的組織方式;
是的,是個公司就會有代碼規範,但那只是寫在紙面上的東西,是否真照着執行了,還真很差說;什麼後期掃描,不改不給上線?
爲工程而生,go強制的編碼規範,讓人耳目一新,從命名、到代碼排列組織方式都有明確的規定,不符合就不能編譯經過!這個真得叫好;代碼工程不是實現個性張揚的地方;多線程
以上聊到的都是go的優勢,看一個爽一個;但go的語法,如變量、函數的聲明和定義,和咱們常見的語言語法相比,都是類型後置,這點着實有些不習慣;
爲啥要這麼搞?
Rob Pike(go語言的建立者之一)針對這個問題給過解釋:不是爲了不同凡響,而是爲了更加清晰易懂。特別是當類型比較複雜時,Go的類型語法要比 C 的容易懂。
詳見:
https://www.zhihu.com/question/21656696/answer/19027040併發
最後,貼幾點Go語言的哲學:
Go語言集衆多編程範式之所長,並以本身獨到的方式將它們融合在一塊兒。程序員們能夠用他們喜歡的風格去設計程序。
相對於設計規則上的靈活,Go語言有着明確且近乎嚴格的編碼規範。咱們能夠經過「go fmt」命令來按照官方的規範格式化代碼。
Go語言是強調軟件工程的編程語言。它自帶了很是豐富的標準命令,涵蓋了軟件生命週期(開發、測試、部署、維護等等)的各個環節。
Go語言是雲計算時代的編程語言。它關注高併發程序,並旨在開發效率和運行效率上取得平衡。
Go語言提倡交換數據,而不是共享數據。它的併發原語Goroutine和Channel是其中的兩大併發編程利器。同時,Go語言也提供了豐富的同步工具,以供程序員們根據場景選用。然而,後者就不屬於語言級別的支持了。
http://www.infoq.com/cn/articles/go-language-introduction異步
Posted by: 大CC | 26JAN,2016
博客:blog.me115.com [訂閱]
Github:大CC