從C++到GO

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

從C++到GO

剛開始接觸Go語言,看了兩本Go語言的書,從c++開發人員的角度來看看go語言的新特性,說下自己感觸較深的幾點:

並發編程

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/12424447

記憶體回收

毫無疑問這個好用,有了記憶體回收,不需要開發人員自行控制記憶體的釋放,這樣可避免一堆問題(重複釋放、忘記釋放記憶體、訪問已釋放的記憶體等);
當然,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)

函數多傳回值

這在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關鍵字的引入,保證錯誤處理的代碼在發現錯誤時一定能夠被調用,不會因為業務分支邏輯上的修改而漏調;

當然,看和誰比了,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

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.