這篇文章將為大家詳細講解有關(guān)Go語言的核心特性有哪些,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
創(chuàng)新互聯(lián)2013年至今,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項目網(wǎng)站建設(shè)、成都做網(wǎng)站網(wǎng)站策劃,項目實施與項目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元邵東做網(wǎng)站,已為上家服務(wù),為邵東各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792
Less can be more
大道至簡,小而蘊真
讓事情變得復(fù)雜很容易,讓事情變得簡單才難
深刻的工程文化
Go語言之所以厲害,是因為它在服務(wù)端的開發(fā)中,總能抓住程序員的痛點,以最直接、簡單、高效、穩(wěn)定的方式來解決問題。這里我們并不會深入討論GO語言的具體語法,只會將語言中關(guān)鍵的、對簡化編程具有重要意義的方面介紹給大家,體驗Go的核心特性。
Go語言在并發(fā)編程方面比絕大多數(shù)語言要簡潔不少,這一點是其最大亮點之一,也是其在未來進入高并發(fā)高性能場景的重要籌碼。
不同于傳統(tǒng)的多進程或多線程,golang的并發(fā)執(zhí)行單元是一種稱為goroutine的協(xié)程。
由于在共享數(shù)據(jù)場景中會用到鎖,再加上GC,其并發(fā)性能有時不如異步復(fù)用IO模型,因此相對于大多數(shù)語言來說,golang的并發(fā)編程簡單比并發(fā)性能更具賣點。
在當(dāng)今這個多核時代,并發(fā)編程的意義不言而喻。當(dāng)然,很多語言都支持多線程、多進程編程,但遺憾的是,實現(xiàn)和控制起來并不是那么令人感覺輕松和愉悅。Golang不同的是,語言級別支持協(xié)程(goroutine)并發(fā)(協(xié)程又稱微線程,比線程更輕量、開銷更小,性能更高),操作起來非常簡單,語言級別提供關(guān)鍵字(go)用于啟動協(xié)程,并且在同一臺機器上可以啟動成千上萬個協(xié)程。協(xié)程經(jīng)常被理解為輕量級線程,一個線程可以包含多個協(xié)程,共享堆不共享棧。協(xié)程間一般由應(yīng)用程序顯式實現(xiàn)調(diào)度,上下文切換無需下到內(nèi)核層,高效不少。協(xié)程間一般不做同步通訊,而golang中實現(xiàn)協(xié)程間通訊有兩種:1)共享內(nèi)存型,即使用全局變量+mutex鎖來實現(xiàn)數(shù)據(jù)共享;2)消息傳遞型,即使用一種獨有的channel機制進行異步通訊。
對比JAVA的多線程和GO的協(xié)程實現(xiàn),明顯更直接、簡單。這就是GO的魅力所在,以簡單、高效的方式解決問題,關(guān)鍵字go,或許就是GO語言最重要的標(biāo)志。
高并發(fā)是Golang語言最大的亮點
從C到C++,從程序性能的角度來考慮,這兩種語言允許程序員自己管理內(nèi)存,包括內(nèi)存的申請和釋放等。因為沒有垃圾回收機制所以C/C++運行起來速度很快,但是隨著而來的是程序員對內(nèi)存使用上的很謹(jǐn)小慎微的考慮。因為哪怕一點不小心就可能會導(dǎo)致“內(nèi)存泄露”使得資源浪費或者“野指針”使得程序崩潰等,盡管C++11后來使用了智能指針的概念,但是程序員仍然需要很小心的使用。后來為了提高程序開發(fā)的速度以及程序的健壯性,java和C#等高級語言引入了GC機制,即程序員不需要再考慮內(nèi)存的回收等,而是由語言特性提供垃圾回收器來回收內(nèi)存。但是隨之而來的可能是程序運行效率的降低。
GC過程是:先stop the world,掃描所有對象判活,把可回收對象在一段bitmap區(qū)中標(biāo)記下來,接著立即start the world,恢復(fù)服務(wù),同時起一個專門gorountine回收內(nèi)存到空閑list中以備復(fù)用,不物理釋放。物理釋放由專門線程定期來執(zhí)行。
GC瓶頸在于每次都要掃描所有對象來判活,待收集的對象數(shù)目越多,速度越慢。一個經(jīng)驗值是掃描10w個對象需要花費1ms,所以盡量使用對象少的方案,比如我們同時考慮鏈表、map、slice、數(shù)組來進行存儲,鏈表和map每個元素都是一個對象,而slice或數(shù)組是一個對象,因此slice或數(shù)組有利于GC。
GC性能可能隨著版本不斷更新會不斷優(yōu)化,這塊沒仔細調(diào)研,團隊中有HotSpot開發(fā)者,應(yīng)該會借鑒jvm gc的設(shè)計思想,比如分代回收、safepoint等。
內(nèi)存自動回收,再也不需要開發(fā)人員管理內(nèi)存
開發(fā)人員專注業(yè)務(wù)實現(xiàn),降低了心智負擔(dān)
只需要new分配內(nèi)存,不需要釋放
初始化階段直接分配一塊大內(nèi)存區(qū)域,大內(nèi)存被切分成各個大小等級的塊,放入不同的空閑list中,對象分配空間時從空閑list中取出大小合適的內(nèi)存塊。內(nèi)存回收時,會把不用的內(nèi)存重放回空閑list??臻e內(nèi)存會按照一定策略合并,以減少碎片。
編譯涉及到兩個問題:編譯速度和依賴管理
目前Golang具有兩種編譯器,一種是建立在GCC基礎(chǔ)上的Gccgo,另外一種是分別針對64位x64和32位x86計算機的一套編譯器(6g和8g)。
依賴管理方面,由于golang絕大多數(shù)第三方開源庫都在github上,在代碼的import中加上對應(yīng)的github路徑就可以使用了,庫會默認(rèn)下載到工程的pkg目錄下。
另外,編譯時會默認(rèn)檢查代碼中所有實體的使用情況,凡是沒使用到的package或變量,都會編譯不通過。這是golang挺嚴(yán)謹(jǐn)?shù)囊幻妗?/p>
由于golang誕生在互聯(lián)網(wǎng)時代,因此它天生具備了去中心化、分布式等特性,具體表現(xiàn)之一就是提供了豐富便捷的網(wǎng)絡(luò)編程接口,比如socket用net.Dial(基于tcp/udp,封裝了傳統(tǒng)的connect、listen、accept等接口)、http用http.Get/Post()、rpc用client.Call('class_name.method_name', args, &reply),等等。
高性能HTTP Server
在C,C++中,包括其他的一些高級語言是不支持多個函數(shù)返回值的。但是這項功能又確實是需要的,所以在C語言中一般通過將返回值定義成一個結(jié)構(gòu)體,或者通過函數(shù)的參數(shù)引用的形式進行返回。而在Go語言中,作為一種新型的語言,目標(biāo)定位為強大的語言當(dāng)然不能放棄對這一需求的滿足,所以支持函數(shù)多返回值是必須的。
函數(shù)定義時可以在入?yún)⒑竺嬖偌?a,b,c),表示將有3個返回值a、b、c。這個特性在很多語言都有,比如python。
這個語法糖特性是有現(xiàn)實意義的,比如我們經(jīng)常會要求接口返回一個三元組(errno,errmsg,data),在大多數(shù)只允許一個返回值的語言中,我們只能將三元組放入一個map或數(shù)組中返回,接收方還要寫代碼來檢查返回值中包含了三元組,如果允許多返回值,則直接在函數(shù)定義層面上就做了強制,使代碼更簡潔安全。
語言交互性指的是本語言是否能和其他語言交互,比如可以調(diào)用其他語言編譯的庫。
在Go語言中直接重用了大部份的C模塊,這里稱為Cgo.Cgo允許開發(fā)者混合編寫C語言代碼,然后Cgo工具可以將這些混合的C代碼提取并生成對于C功能的調(diào)用包裝代碼。開發(fā)者基本上可以完全忽略這個Go語言和C語言的邊界是如何跨越的。
golang可以和C程序交互,但不能和C++交互。可以有兩種替代方案:1)先將c++編譯成動態(tài)庫,再由go調(diào)用一段c代碼,c代碼通過dlfcn庫動態(tài)調(diào)用動態(tài)庫(記得export LD_LIBRARY_PATH);2)使用swig(沒玩過)
golang不支持try...catch這樣的結(jié)構(gòu)化的異常解決方式,因為覺得會增加代碼量,且會被濫用,不管多小的異常都拋出。golang提倡的異常處理方式是:
普通異常:被調(diào)用方返回error對象,調(diào)用方判斷error對象。
嚴(yán)重異常:指的是中斷性panic(比如除0),使用defer...recover...panic機制來捕獲處理。嚴(yán)重異常一般由golang內(nèi)部自動拋出,不需要用戶主動拋出,避免傳統(tǒng)try...catch寫得到處都是的情況。當(dāng)然,用戶也可以使用panic('xxxx')主動拋出,只是這樣就使這一套機制退化成結(jié)構(gòu)化異常機制了。
類型推導(dǎo):類型定義:支持var abc = 10
這樣的語法,讓golang看上去有點像動態(tài)類型語言,但golang實際上時強類型的,前面的定義會被自動推導(dǎo)出是int類型。
作為強類型語言,隱式的類型轉(zhuǎn)換是不被允許的,記住一條原則:讓所有的東西都是顯式的。
簡單來說,Go是一門寫起來像動態(tài)語言,有著動態(tài)語言開發(fā)效率的靜態(tài)語言。
一個類型只要實現(xiàn)了某個interface的所有方法,即可實現(xiàn)該interface,無需顯式去繼承。
Go編程規(guī)范推薦每個Interface只提供一到兩個的方法。這樣使得每個接口的目的非常清晰。另外Go的隱式推導(dǎo)也使得我們組織程序架構(gòu)的時候更加靈活。在寫JAVA/C++程序的時候,我們一開始就需要把父類/子類/接口設(shè)計好,因為一旦后面有變更,修改起來會非常痛苦。而Go不一樣,當(dāng)你在實現(xiàn)的過程中發(fā)現(xiàn)某些方法可以抽象成接口的時候,你直接定義好這個接口就OK了,其他代碼不需要做任何修改,編譯器的自動推導(dǎo)會幫你做好一切。
不能循環(huán)引用:即如果a.go中import了b,則b.go要是import a會報import cycle not allowed。好處是可以避免一些潛在的編程危險,比如a中的func1()調(diào)用了b中的func2(),如果func2()也能調(diào)用func1(),將會導(dǎo)致無限循環(huán)調(diào)用下去。
defer機制:在Go語言中,提供關(guān)鍵字defer,可以通過該關(guān)鍵字指定需要延遲執(zhí)行的邏輯體,即在函數(shù)體return前或出現(xiàn)panic時執(zhí)行。這種機制非常適合善后邏輯處理,比如可以盡早避免可能出現(xiàn)的資源泄漏問題。
可以說,defer是繼goroutine和channel之后的另一個非常重要、實用的語言特性,對defer的引入,在很大程度上可以簡化編程,并且在語言描述上顯得更為自然,極大的增強了代碼的可讀性。
“包”的概念:和python一樣,把相同功能的代碼放到一個目錄,稱之為包。包可以被其他包引用。main包是用來生成可執(zhí)行文件,每個程序只有一個main包。包的主要用途是提高代碼的可復(fù)用性。通過package可以引入其他包。
編程規(guī)范:GO語言的編程規(guī)范強制集成在語言中,比如明確規(guī)定花括號擺放位置,強制要求一行一句,不允許導(dǎo)入沒有使用的包,不允許定義沒有使用的變量,提供gofmt工具強制格式化代碼等等。奇怪的是,這些也引起了很多程序員的不滿,有人發(fā)表GO語言的XX條罪狀,里面就不乏對編程規(guī)范的指責(zé)。要知道,從工程管理的角度,任何一個開發(fā)團隊都會對特定語言制定特定的編程規(guī)范,特別像Google這樣的公司,更是如此。GO的設(shè)計者們認(rèn)為,與其將規(guī)范寫在文檔里,還不如強制集成在語言里,這樣更直接,更有利用團隊協(xié)作和工程管理。
交叉編譯:比如說你可以在運行 Linux 系統(tǒng)的計算機上開發(fā)運行 Windows 下運行的應(yīng)用程序。這是第一門完全支持 UTF-8 的編程語言,這不僅體現(xiàn)在它可以處理使用 UTF-8 編碼的字符串,就連它的源碼文件格式都是使用的 UTF-8 編碼。Go 語言做到了真正的國際化!
此處我們說個小段子:
很久以前,有一個IT公司,這公司有個傳統(tǒng),允許員工擁有20%自由時間來開發(fā)實驗性項目。在2007的某一天,公司的幾個大牛,正在用c++開發(fā)一些比較繁瑣但是核心的工作,主要包括龐大的分布式集群,大牛覺得很鬧心,后來c++委員會來他們公司演講,說c++將要添加大概35種新特性。這幾個大牛的其中一個人,名為:Rob Pike,聽后心中一萬個xxx飄過,“c++特性還不夠多嗎?簡化c++應(yīng)該更有成就感吧”。于是乎,Rob Pike和其他幾個大牛討論了一下,怎么解決這個問題,過了一會,Rob Pike說要不我們自己搞個語言吧,名字叫“go”,非常簡短,容易拼寫。其他幾位大牛就說好啊,然后他們找了塊白板,在上面寫下希望能有哪些功能。接下來的時間里,大牛們開心的討論設(shè)計這門語言的特性,經(jīng)過漫長的歲月,他們決定,以c語言為原型,以及借鑒其他語言的一些特性,來解放程序員,解放自己,然后在2009年,go語言誕生。
以下就是這些大牛所羅列出的Go要有的功能:
規(guī)范的語法(不需要符號表來解析)
垃圾回收(獨有)
無頭文件
明確的依賴
無循環(huán)依賴
常量只能是數(shù)字
int和int32是兩種類型
字母大小寫設(shè)置可見性(letter case sets visibility)
任何類型(type)都有方法(不是類型)
沒有子類型繼承(不是子類)
包級別初始化以及明確的初始化順序
文件被編譯到一個包里
包package-level globals presented in any order
沒有數(shù)值類型轉(zhuǎn)換(常量起輔助作用)
接口隱式實現(xiàn)(沒有“implement”聲明)
嵌入(不會提升到超類)
方法按照函數(shù)聲明(沒有特別的位置要求)
方法即函數(shù)
接口只有方法(沒有數(shù)據(jù))
方法通過名字匹配(而非類型)
沒有構(gòu)造函數(shù)和析構(gòu)函數(shù)
postincrement(如++i)是狀態(tài),不是表達式
沒有preincrement(i++)和predecrement
賦值不是表達式
明確賦值和函數(shù)調(diào)用中的計算順序(沒有“sequence point”)
沒有指針運算
內(nèi)存一直以零值初始化
局部變量取值合法
方法中沒有“this”
分段的堆棧
沒有靜態(tài)和其它類型的注釋
沒有模板
內(nèi)建string、slice和map
數(shù)組邊界檢查
關(guān)于“Go語言的核心特性有哪些”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,使各位可以學(xué)到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
本文名稱:Go語言的核心特性有哪些
當(dāng)前鏈接:http://chinadenli.net/article26/pipcjg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開發(fā)、網(wǎng)站制作、品牌網(wǎng)站設(shè)計、靜態(tài)網(wǎng)站、品牌網(wǎng)站建設(shè)、營銷型網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)