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語言有一個大概的了解,後面我們會為大家做詳細的介紹。