Go語言的特性有哪些?

2020-07-16 10:05:13
Go語言也稱為 Golang,是由 Google 公司開發的一種靜態強型別、編譯型、並行型、並具有垃圾回收功能的程式語言。

Go語言的特性可以歸納為以下幾點:
  • 自動垃圾回收
  • 更豐富的內建型別
  • 函數多返回值
  • 錯誤處理
  • 物件導向
  • 並行程式設計
  • 反射
  • 語言互動性
  • 編譯

下面就來分別介紹一下。

1) 自動垃圾回收

曾幾何時,記憶體管理是應用開發的一大難題,傳統的系統級程式語言 C/C++ 中,開發人員必須小心的對記憶體進行管理操作,控制記憶體的申請及釋放。處理不當,就可能產生記憶體洩露問題,這種問題不易發現並且難以定位,一直成為困擾開發人員的障礙。

與 C/C++ 語言不同,在Go語言中不需要開發人員時刻考慮著記憶體的回收,Go語言內建的垃圾回收器會自動幫我們完成這些工作,大大提高了我們的開發效率。

2) 更豐富的內建型別

除了幾乎所有語言都支援的簡單內建型別(比如整型、浮點型等)外,Go語言還支援一些其他的高階型別,比如字典型別,字典型別在其他語言中都是通過包的形式引入的外部資料型別。

此外還有陣列切片(Slice),它在Go語言中也是一種內建的資料型別,通常作為動態陣列來使用,類似於 C++ STL 中的 vector。

3) 函數多返回值

在C語言以及其他的一些高階語言中函數是不支援包含多個返回值的,但是這項功能又確實是需要的,所以在C語言中一般通過將返回值定義成一個結構體,或者通過函數的引數參照的形式進行返回。

Go語言在靜態語言陣營中率先提供了函數的多返回值功能。這個特性讓開發人員可以在函數內部同時 return 多個返回值,不用再為了返回多個值而專門定義一個資料型別。

4) 錯誤處理

在傳統的物件導向(OOP)程式設計中,為了確保程式的健壯性需要捕獲異常,使用的方法大都是 try...catch 語句。

在Go語言中不支援 try...catch 這樣的例外處理方式,而是引入了三個關鍵字,分別是 defer、panic 和 recover,其中使用 defer 語句的含義是不管程式是否出現異常,均在函數退出時自動執行相關程式碼,另外兩個關鍵字則是分別用來終止程式和讓終止的程式恢復執行。

Go語言的錯誤處理機制可以減少程式碼量,讓開發人員無需使用大量的 try...catch 語句,有利於後期程式碼的閱讀和維護。

5) 物件導向

Go語言雖然支援物件導向程式設計,但是和傳統的物件導向有區別,去掉了傳統物件導向的繼承、方法過載、建構函式和解構函式等等,所以說Go語言並不是純粹的物件導向程式語言。

而且,Go語言中沒有類的概念,但是Go語言的結構體(struct)和其他語言的類(Class)有同等地位,也就是說Go語言是基於結構體來實現物件導向概念的。

6) 並行程式設計

Go語言引入了 goroutine(輕量級執行緒)概念,goroutine 是一種比執行緒更加輕盈、更省資源的協程,通過在函數呼叫前使用關鍵字 go,即可讓該函數以 goroutine 方式執行。

同時,Go語言使用 channel(通道)這個概念實現了 CSP(交談循序程式,Communicating Sequential Process)模型來作為 goroutine  間的通訊方式。channel 的使用方式比較接近 Unix 系統中的管道(pipe)概念,可以方便地進行跨 goroutine 的通訊。

Go語言通過使用 goroutine 而不是直接使用作業系統的併行機制,以及使用 channel 來進行跨 goroutine 通訊而不是使用共用記憶體來通訊,這讓並行程式設計變得更加安全和便捷。

7) 反射

反射(reflection)是在Java語言出現後迅速流行起來的一種概念。通過反射,可以獲取物件型別的詳細資訊,並可動態操作物件。反射是把雙刃劍,功能強大但程式碼可讀性並不理想,若非必要,並不推薦使用反射。

Go語言中的反射和 Java 中的反射類似,但沒有像Java語言那樣內建型別工廠,所以無法做到像 Java 那樣通過型別字串建立物件範例。

Go語言中反射最常見的使用場景是對資料進行格式化(有時候也叫 Marshal & Unmarshal)。例如,Go語言標準庫的 encoding/json、encoding/xml、encoding/gob、encoding/binary 等包就大量依賴於反射功能來實現。

8) 語言的互動性

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

因為Go語言與C語言之間存在天生聯絡(Go語言是以C語言為原型而設計的),所以在Go語言中直接重用了大部份的 C 模組,這裡稱為 Cgo。Cgo 既是語言特性,同時也是一個工具的名稱。

在Go語言程式碼中,可以按 Cgo 的特定語法混合編寫C語言程式碼,然後 Cgo 可以將這些混合的C語言程式碼提取並生成用於呼叫C功能的程式碼。開發者基本上可以完全忽略Go語言和C語言的邊界是如何跨越的。

9) 編譯

編譯涉及到兩個問題,分別是編譯速度和依賴管理。
  • 編譯速度:Go語言的程式碼編譯速度非常快,所以,根本無需為編譯程式碼而等待太長的時間,當你使用 go run 命令執行一段程式的時候,幾乎感受不到程式的編譯過程。
  • 依賴管理:由於Go語言絕大多數第三方開源庫都在 github 上,所以在需要參照某個庫時,直接在程式碼的 import 中加上該庫對應的 github 路徑就可以使用了,庫會預設下載到工程的 pkg 目錄下。

另外,編譯時編譯器會預設檢查程式碼中所有變數、方法、庫等等的使用情況,只要存在沒有使用到的,都會編譯不通過。

以上便是本節中總結出來的Go語言的特性,大家可能會有很多不理解的地方,不過沒有關係,本節主要是為了讓剛剛接觸Go語言的讀者對Go語言有一個大概的了解,後面我們會為大家做詳細的介紹。