go語言最重要功能是:1、並發程式設計;go語法上的並發程式設計極為容易,無須處理回調,無須專注於線程切換,僅一個關鍵字,簡單而自然。 2、自動回收垃圾;程式設計師不需要再考慮記憶體的回收等,而是由語言特性提供垃圾回收器來回收記憶體。 3、更豐富的內建類型。 4.函數的多重返回值。 5、錯誤處理。 6.匿名函數和閉包。 7、類型和接口。 8.反射,可以讓開發者將型別本身當作第一類的值型別處理。 9.語言互動性。
本教學操作環境:windows7系統、GO 1.18版本、Dell G3電腦。
Go語言最重要的特徵如下:
#並發程式設計
自動回收垃圾
更豐富的內建類型
#函數的多重傳回值
錯誤處理
匿名函數與閉包
#類型和介面
#反射語言互動性
並行程式設計
時至今日,並發程式設計已成為程式設計師的基本技能,在各個技術社群中都能看到許多與之相關的討論主題。在這種情況下Go語言卻一反常態做了件極大大膽的事,從根本上將一切都並發化,運行時用 Goroutine 運行所有的一切,包括 main.main 入口函數。 可以說,Goroutine 是 Go 最顯著的特徵。它用類別協程的方式來處理並發單元,卻在運行時層面做了更深度的最佳化處理。這使得語法上的並發編程變得極為容易,無須處理回調,無須關注線程切換,僅一個關鍵字,簡單而自然。 Go語言在並發程式設計方面比絕大多數語言要簡潔不少,這一點是其最大亮點之一,也是其在未來進入高並發高效能場景的重要籌碼。不同於傳統的多進程或多線程,golang的並發執行單元是一種稱為goroutine的協程。
由於在共享資料場景中會用到鎖,再加上GC,其並發性能有時不如異步復用IO模型,因此相對於大多數語言來說,golang的並發程式設計簡單比並發性能更具賣點。 在當今這個多核心時代,並發程式設計的意義不言而喻。當然,很多語言都支援多執行緒、多進程編程,但遺憾的是,實現和控制起來並不是那麼令人感覺輕鬆和愉悅。 Golang不同的是,語言等級支援協程(goroutine)並發(協程又稱微線程,比線程更輕、開銷更小,效能更高),操作起來非常簡單,語言層級提供關鍵字(go)用於啟動協程,並且在同一台機器上可以啟動成千上萬個協程。協程經常被理解為輕量級線程,一個線程可以包含多個協程,共享堆不共享堆疊。協程間一般由應用程式明確實現調度,上下文切換無需下到核心層,高效不少。協程間一般不做同步通訊,而golang中實作協程間通訊有兩種:1)共享記憶體型,即使用全域變數mutex鎖來實現資料共享;2)訊息傳遞型,即使用一種獨有的channel機制進行非同步通訊。 比較JAVA的多執行緒和GO的協程實現,明顯更直接、簡單。這就是GO的魅力所在,以簡單、有效率的方式解決問題,關鍵字go,或許就是GO語言最重要的標誌。
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語言最重要特徵是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!