go語言最重要特性是什麼

2022-12-16 22:01:07

go語言最重要特性是:1、並行程式設計;go語法上的並行程式設計極為容易,無須處理回撥,無須關注執行緒切換,僅一個關鍵字,簡單而自然。2、自動回收垃圾;程式設計師不需要再考慮記憶體的回收等,而是由語言特性提供垃圾回收器來回收記憶體。3、更豐富的內建型別。4、函數的多返回值。5、錯誤處理。6、匿名函數和閉包。7、型別和介面。8、反射,可以讓開發者將型別本身作為第一類的值型別處理。9、語言互動性。

php入門到就業線上直播課:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API偵錯工具:

本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。

Go語言最重要的特徵如下:

  • 並行程式設計

  • 自動回收垃圾

  • 更豐富的內建型別

  • 函數的多返回值

  • 錯誤處理

  • 匿名函數和閉包

  • 型別和介面

  • 反射

  • 語言互動性

並行程式設計

時至今日,並行程式設計已成為程式設計師的基本技能,在各個技術社群都能看到諸多與之相關的討論主題。在這種情況下Go語言卻一反常態做了件極大膽的事,從根本上將一切都並行化,執行時用 Goroutine 執行所有的一切,包括 main.main 入口函數。

可以說,Goroutine 是 Go 最顯著的特徵。它用類協程的方式來處理並行單元,卻又在執行時層面做了更深度的優化處理。這使得語法上的並行程式設計變得極為容易,無須處理回撥,無須關注執行緒切換,僅一個關鍵字,簡單而自然。

Go語言在並行程式設計方面比絕大多數語言要簡潔不少,這一點是其最大亮點之一,也是其在未來進入高並行高效能場景的重要籌碼。

1.png

不同於傳統的多程序或多執行緒,golang的並行執行單元是一種稱為goroutine的協程。

由於在共用資料場景中會用到鎖,再加上GC,其並行效能有時不如非同步複用IO模型,因此相對於大多數語言來說,golang的並行程式設計簡單比並行效能更具賣點。

在當今這個多核時代,並行程式設計的意義不言而喻。當然,很多語言都支援多執行緒、多程序程式設計,但遺憾的是,實現和控制起來並不是那麼令人感覺輕鬆和愉悅。Golang不同的是,語言級別支援協程(goroutine)並行(協程又稱微執行緒,比執行緒更輕量、開銷更小,效能更高),操作起來非常簡單,語言級別提供關鍵字(go)用於啟動協程,並且在同一臺機器上可以啟動成千上萬個協程。協程經常被理解為輕量級執行緒,一個執行緒可以包含多個協程,共用堆不共用棧。協程間一般由應用程式顯式實現排程,上下文切換無需下到核心層,高效不少。協程間一般不做同步通訊,而golang中實現協程間通訊有兩種:1)共用記憶體型,即使用全域性變數+mutex鎖來實現資料共用;2)訊息傳遞型,即使用一種獨有的channel機制進行非同步通訊。

對比JAVA的多執行緒和GO的協程實現,明顯更直接、簡單。這就是GO的魅力所在,以簡單、高效的方式解決問題,關鍵字go,或許就是GO語言最重要的標誌。

高並行是Golang語言最大的亮點

記憶體回收(GC)

從C到C++,從程式效能的角度來考慮,這兩種語言允許程式設計師自己管理記憶體,包括記憶體的申請和釋放等。因為沒有垃圾回收機制所以C/C++執行起來速度很快,但是隨著而來的是程式設計師對記憶體使用上的很謹小慎微的考慮。因為哪怕一點不小心就可能會導致「記憶體洩露」使得資源浪費或者「野指標」使得程式崩潰等,儘管C++11後來使用了智慧指標的概念,但是程式設計師仍然需要很小心的使用。後來為了提高程式開發的速度以及程式的健壯性,java和C#等高階語言引入了GC機制,即程式設計師不需要再考慮記憶體的回收等,而是由語言特性提供垃圾回收器來回收記憶體。但是隨之而來的可能是程式執行效率的降低。

GC過程是:先stop the world,掃描所有物件判活,把可回收物件在一段bitmap區中標記下來,接著立即start the world,恢復服務,同時起一個專門gorountine回收記憶體到空閒list中以備複用,不物理釋放。物理釋放由專門執行緒定期來執行。

GC瓶頸在於每次都要掃描所有物件來判活,待收集的物件數目越多,速度越慢。一個經驗值是掃描10w個物件需要花費1ms,所以儘量使用物件少的方案,比如我們同時考慮連結串列、map、slice、陣列來進行儲存,連結串列和map每個元素都是一個物件,而slice或陣列是一個物件,因此slice或陣列有利於GC。

GC效能可能隨著版本不斷更新會不斷優化,這塊沒仔細調研,團隊中有HotSpot開發者,應該會借鑑jvm gc的設計思想,比如分代回收、safepoint等。

  • 記憶體自動回收,再也不需要開發人員管理記憶體

  • 開發人員專注業務實現,降低了心智負擔

  • 只需要new分配記憶體,不需要釋放

更豐富的內建型別

關鍵在於內建,像map、slice這些常用的資料型別,內建於builtin,預設包含,無需自己新增。

函數多返回值

在C,C++中,包括其他的一些高階語言是不支援多個函數返回值的。但是這項功能又確實是需要的,所以在C語言中一般通過將返回值定義成一個結構體,或者通過函數的引數參照的形式進行返回。而在Go語言中,作為一種新型的語言,目標定位為強大的語言當然不能放棄對這一需求的滿足,所以支援函數多返回值是必須的。

函數定義時可以在入參後面再加(a,b,c),表示將有3個返回值a、b、c。這個特性在很多語言都有,比如python。

這個語法糖特性是有現實意義的,比如我們經常會要求介面返回一個三元組(errno,errmsg,data),在大多數只允許一個返回值的語言中,我們只能將三元組放入一個map或陣列中返回,接收方還要寫程式碼來檢查返回值中包含了三元組,如果允許多返回值,則直接在函數定義層面上就做了強制,使程式碼更簡潔安全。

語言互動性

語言互動性指的是本語言是否能和其他語言互動,比如可以呼叫其他語言編譯的庫。

在Go語言中直接重用了大部份的C模組,這裡稱為Cgo.Cgo允許開發者混合編寫C語言程式碼,然後Cgo工具可以將這些混合的C程式碼提取並生成對於C功能的呼叫包裝程式碼。開發者基本上可以完全忽略這個Go語言和C語言的邊界是如何跨越的。

golang可以和C程式互動,但不能和C++互動。可以有兩種替代方案:1)先將c++編譯成動態庫,再由go呼叫一段c程式碼,c程式碼通過dlfcn庫動態呼叫動態庫(記得export LD_LIBRARY_PATH);2)使用swig(沒玩過)

例外處理

golang不支援try…catch這樣的結構化的異常解決方式,因為覺得會增加程式碼量,且會被濫用,不管多小的異常都丟擲。golang提倡的例外處理方式是:

普通異常:被呼叫方返回error物件,呼叫方判斷error物件。

嚴重異常:指的是中斷性panic(比如除0),使用defer…recover…panic機制來捕獲處理。嚴重異常一般由golang內部自動丟擲,不需要使用者主動丟擲,避免傳統try…catch寫得到處都是的情況。當然,使用者也可以使用panic('xxxx')主動丟擲,只是這樣就使這一套機制退化成結構化異常機制了。

反射(reflection)

Go語言提供了一種機制在執行時更新和檢查變數的值、呼叫變數的方法和變數支援的內在操作,但是在編譯時並不知道這些變數的具體型別,這種機制被稱為反射。反射也可以讓我們將型別本身作為第一類的值型別處理。

反射是指在程式執行期對程式本身進行存取和修改的能力,程式在編譯時變數被轉換為記憶體地址,變數名不會被編譯器寫入到可執行部分,在執行程式時程式無法獲取自身的資訊。

支援反射的語言可以在程式編譯期將變數的反射資訊,如欄位名稱、型別資訊、結構體資訊等整合到可執行檔案中,並給程式提供介面存取反射資訊,這樣就可以在程式執行期獲取型別的反射資訊,並且有能力修改它們。

C/C++語言沒有支援反射功能,只能通過 typeid 提供非常弱化的程式執行時型別資訊;Java、C# 等語言都支援完整的反射功能;Lua、JavaScript 類動態語言,由於其本身的語法特性就可以讓程式碼在執行期存取程式自身的值和型別資訊,因此不需要反射系統。

Go語言程式的反射系統無法獲取到一個可執行檔案空間中或者是一個包中的所有型別資訊,需要配合使用標準庫中對應的詞法、語法解析器和抽象語法樹(AST)對原始碼進行掃描後獲得這些資訊。

【相關推薦:Go視訊教學、】

以上就是go語言最重要特性是什麼的詳細內容,更多請關注TW511.COM其它相關文章!