官术网_书友最值得收藏!

1.1 Go的語言特性

Go語言于2009年11月正式發(fā)布,它是谷歌公司開發(fā)的一種語法簡單、原生支持并發(fā)、靜態(tài)強(qiáng)類型的編譯型語言。Go程序可以運(yùn)行在多種平臺上,可在Linux、Mac OS X和Microsoft Windows操作系統(tǒng)上運(yùn)行。在撰寫此書時,Go最新的版本為1.13.4。Go語言在設(shè)計(jì)時吸收了眾多語言的優(yōu)勢,并盡量保持簡潔且實(shí)用。

Go語言在語法上和C語言非常相似,被稱為面向21世紀(jì)的C語言,可見其在編程語言中的地位。Go語言的設(shè)計(jì)理念是大道至簡(Less Can Be More)。

Go語言的三位創(chuàng)始人是編程界的大神級人物,分別是羅伯特·格瑞史莫(Robert Griesemer)、羅勃·派克(Rob Pike)及肯·湯普遜(Ken Thompson)。其中,Ken Thompson是UNIX的發(fā)明人之一、C語言的前身B語言的發(fā)明者和1983年的圖靈獎獲得者,而Robert Griesemer是Google V8 JS Engine和Hot Spot的開發(fā)者。

Go語言雖然是靜態(tài)編譯型語言,但是它擁有腳本化的語法,支持多種編程范式,如支持函數(shù)式編程和面向?qū)ο缶幊?。原生支持并發(fā)編程的特性應(yīng)該是Go語言最讓人著迷的地方,開發(fā)人員可以通過goroutine這種輕量級線程的技術(shù)來實(shí)現(xiàn)并發(fā)編程的目標(biāo)。

Go語言主要在多核硬件架構(gòu)、超大規(guī)模分布式計(jì)算集群和Web應(yīng)用上具有明顯的優(yōu)勢。Go語言最主要的特性有如下幾個方面。

1.原生支持并發(fā)

對于Web應(yīng)用來說,高并發(fā)和高性能是其追求的目標(biāo)之一。就高并發(fā)的程序而言,如何保證線程安全非常重要。與Java和.NET等語言相比,Go語言在并發(fā)編程方面要簡潔很多,這也是Go語言適合編寫高并發(fā)、高性能應(yīng)用的前提。Go語言的并發(fā)執(zhí)行單元被稱為協(xié)程(Goroutine),可以看作是一種微線程,它比線程更輕量、開銷更小、性能更高。Go語言原生提供關(guān)鍵字go來啟動協(xié)程,在一臺機(jī)器上可以啟動成千上萬個協(xié)程。

注意

Go語言原生支持并發(fā),但是不能保證并發(fā)時線程一定是安全的,線程安全仍然需要用鎖等技術(shù)進(jìn)行實(shí)現(xiàn)。

2.自動垃圾回收

C和C++編寫的程序性能往往很高、運(yùn)行速度比較快,但是這兩種語言需要開發(fā)人員手動管理內(nèi)存,包括內(nèi)存的申請和釋放等。由于沒有垃圾回收機(jī)制,因此C和C++編寫的程序一不小心就可能會導(dǎo)致內(nèi)存泄漏,進(jìn)而導(dǎo)致程序甚至系統(tǒng)崩潰。內(nèi)存泄漏這種問題不易發(fā)現(xiàn)并且難以調(diào)試。內(nèi)存泄漏的最佳解決方案是在語言級別引入自動垃圾回收機(jī)制(Garbage Collection,GC)。

Java和.NET等高級語言引入了垃圾回收機(jī)制,內(nèi)存釋放由虛擬機(jī)(Virtual Machine)或運(yùn)行時(Runtime)系統(tǒng)來自動進(jìn)行管理。Go語言也具有自動垃圾回收機(jī)制,因此可以解放開發(fā)人員讓他們專注業(yè)務(wù)邏輯的實(shí)現(xiàn)。

注意

Go語言雖然有自動垃圾回收機(jī)制,但是在編寫代碼時,對于確定不用的對象,建議手動進(jìn)行釋放,這樣可以避免自動垃圾回收機(jī)制不及時對內(nèi)存進(jìn)行回收而導(dǎo)致的內(nèi)存泄漏問題。

3.更豐富的內(nèi)置數(shù)據(jù)類型

Go語言除了內(nèi)置簡單數(shù)據(jù)類型(如整數(shù)類型和浮點(diǎn)類型等)和高級數(shù)據(jù)類型(數(shù)組類型和字符串類型)外,還內(nèi)置了map類型(字典類型,也被稱為映射類型)和slice類型(切片類型)。slice類型底層其實(shí)是一種可動態(tài)增長的數(shù)組。這幾種數(shù)據(jù)類型基本上覆蓋了絕大部分的應(yīng)用場景。數(shù)組切片的功能與C++標(biāo)準(zhǔn)庫中的vector非常類似。

由于Go語言內(nèi)置了更加豐富的數(shù)據(jù)類型,因此編寫代碼就更加簡潔,例如不用額外導(dǎo)入包或模塊就可以使用map和slice類型。

4.函數(shù)可有多個返回值

當(dāng)前的主流語言中除Python外,基本都不支持函數(shù)有多個返回值,比如C和C++。雖然這項(xiàng)功能非常實(shí)用,但是C語言并不支持,C語言為了解決多個返回值的問題,一般只能將函數(shù)返回值定義為一個結(jié)構(gòu)體。

而Go語言原生就支持函數(shù)有多個返回值。在Go語言中,如果開發(fā)者只需要用到函數(shù)某幾個返回值,而不是全部的返回值,則可以用下劃線(_)作為占位符來忽略不關(guān)心的返回值。

5.語言的互操作性和指針

Go語言的互操作性指的是可以和其他語言進(jìn)行互操作,如調(diào)用其他語言編譯的庫。Go語言允許開發(fā)者調(diào)用C語言代碼。

此外,C語言和C++中很重要的一個概念就是指針。指針比較抽象,而且不容易掌握。Go語言也提供了指針,但并不能像C語言那樣進(jìn)行指針運(yùn)算(安全模式下),而必須在所謂的非安全模式下。Go語言允許我們控制特定集合的數(shù)據(jù)結(jié)構(gòu)、分配的數(shù)量以及內(nèi)存訪問模式,這對于構(gòu)建運(yùn)行良好的系統(tǒng)是非常重要的。正確地使用指針,可以達(dá)到提升性能和減少內(nèi)存占用的目的。在系統(tǒng)編程或者網(wǎng)絡(luò)應(yīng)用等方面,指針往往不可或缺。

6.異常處理

Go語言不支持try...catch這種結(jié)構(gòu)化的異常處理方式,因?yàn)檫@種異常處理會增加代碼量且可能會被濫用。Go語言提倡的異常處理方式是:

· 普通異常:被調(diào)用方返回error對象,調(diào)用方判斷error對象。

· 嚴(yán)重異常:中斷性panic(比如除0),使用defer...recover...panic機(jī)制來捕獲處理。嚴(yán)重異常一般由Go內(nèi)部自動拋出,不需要用戶主動拋出。當(dāng)然,開發(fā)人員也可以使用panic主動拋出異常(錯誤)。

7.類型推導(dǎo)和接口

Go語言支持“var a =7”語法,這讓Go語言有點(diǎn)像動態(tài)類型語言,但它實(shí)際上是強(qiáng)類型語言,只是變量a定義時會被自動推導(dǎo)出是整數(shù)類型。Go語言在代碼風(fēng)格上像動態(tài)類型語言,在運(yùn)行效率上則像靜態(tài)編譯型語言。

Go語言用關(guān)鍵字struct來自定義類型,與C語言中的結(jié)構(gòu)非常接近。同時Go語言還引入了一個無比強(qiáng)大的非侵入式接口的概念,只要某個對象實(shí)現(xiàn)了某個接口的定義,就會認(rèn)為實(shí)現(xiàn)了該接口,而不用顯式的語法來實(shí)現(xiàn)。

Go語言提供了靈活、無繼承的類型系統(tǒng),無須降低運(yùn)行性能就能最大程度復(fù)用代碼。這個類型系統(tǒng)依然支持面向?qū)ο蟮拈_發(fā),同時避免了傳統(tǒng)面向?qū)ο蟮膯栴}。在Go語言中,一個類型由其他更微小的類型組合而成,從而避免了使用傳統(tǒng)的基于繼承的類型系統(tǒng)。

8.規(guī)范的語法

Go語言的編程規(guī)范強(qiáng)制融入到語言中,比如明確規(guī)定大括號擺放的位置、強(qiáng)制要求一行一條程序語句、不允許導(dǎo)入沒有使用的包、不允許定義沒有使用的變量、提供gofmt工具強(qiáng)制格式化代碼等。

從工程管理的角度,任何一個開發(fā)團(tuán)隊(duì)都會對特定的語言制定一定的編程規(guī)范,方便團(tuán)隊(duì)協(xié)作。Go語言的設(shè)計(jì)者們認(rèn)為,將規(guī)范寫在文檔里,還不如從語言層面以強(qiáng)制方式進(jìn)行約束,這樣更加直接,更有利于團(tuán)隊(duì)協(xié)作和工程管理。

Go語言規(guī)范的語法,可以讓不同團(tuán)隊(duì)編寫的代碼更加趨于一致,這樣也更加易于理解。Go語言編寫的程序往往比其他語言更加易于閱讀、更加簡潔。

9.閉包和匿名函數(shù)

在Go語言中,函數(shù)可以作為另外一個函數(shù)的參數(shù)進(jìn)行傳遞。Go語言支持常規(guī)的匿名函數(shù)和閉包,開發(fā)者可以隨意對該匿名函數(shù)變量進(jìn)行傳遞和調(diào)用。Go語言閉包經(jīng)常出現(xiàn)在這樣的應(yīng)用場景中,一個函數(shù)的返回值作為參數(shù)傳遞給另一個函數(shù)。

在Go語言中,閉包的價值在于函數(shù)可以存儲到變量中,作為參數(shù)傳遞給其他函數(shù),最重要的是能夠被函數(shù)動態(tài)創(chuàng)建和返回。Go語言中的閉包同樣也會引用到函數(shù)外的變量。閉包的實(shí)現(xiàn)確保只要閉包還被使用,被閉包引用的變量就會一直存在。

注意

由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,只要閉包在使用,其引用的變量就不會消失,因此內(nèi)存消耗比較大。

10.反射

反射(reflect)技術(shù)是一種比較高級的功能,經(jīng)常出現(xiàn)在框架類的工具開發(fā)中,在Java或者.NET語言中會用到。反射就是用來檢測存儲在接口變量內(nèi)部值(Value)和類型(Type)的一種機(jī)制。Go語言的反射包提供了兩個方法,分別是reflect.ValueOf和reflect.TypeOf。

通過反射,我們可以獲取對象類型的詳細(xì)信息,并可動態(tài)操作對象。反射雖然功能非常強(qiáng)大,但是代碼可讀性不高且執(zhí)行效率比較低。因此若沒有必要,不推薦使用反射。

11.內(nèi)置Runtime

Go語言和Java不同,沒有JVM虛擬機(jī)這一層,Go程序編譯后的二進(jìn)制文件中內(nèi)置了Go Runtime相關(guān)庫。因此,發(fā)布Go程序無須安裝額外的運(yùn)行時環(huán)境。Runtime負(fù)責(zé)管理任務(wù)調(diào)度、垃圾收集與運(yùn)行環(huán)境等。

主站蜘蛛池模板: 开江县| 简阳市| 霞浦县| 建宁县| 榆林市| 濮阳县| 名山县| 洱源县| 伊金霍洛旗| 台中县| 明溪县| 新龙县| 德惠市| 深泽县| 乡宁县| 介休市| 汝城县| 璧山县| 阿合奇县| 芜湖市| 中山市| 海原县| 彩票| 延庆县| 二连浩特市| 阳江市| 会同县| 融水| 固安县| 阿拉善左旗| 阿拉善盟| 漳浦县| 黄山市| 塔河县| 武乡县| 抚宁县| 崇州市| 吉水县| 锡林浩特市| 阜康市| 青铜峡市|