GO語言中的幾個關鍵思想


GO語言的設計理念與C++,Java,Python之流大相徑庭。

一、沒有函數重載

GO語言里面沒有函數重載,Java、C#、C++三位大牛都是支持函數重載的,Python雖然不支持函數重載,但是支持默認形參,這在很大程度上緩解了沒有函數重載的不足。

GO語言不支持函數重載主要是為了簡單,像C語言一樣不支持重載。

二、方法是第一等公民,奇葩而靈活的面向對象

GO語言中沒有class關鍵字,它的面向對象是對C語言中struct的擴展。
結構體像一個插線板,函數像插頭,想給結構體添加什么功能直接在插線板上插入就可以了。
面向對象,一言以蔽之,就是把若干個數據跟若干個方法打包成一團。GO語言中除了結構體就是方法,但是方法可以多了一種屬性:結構體屬性。

C#中的擴展方法跟GO語言中的方法非常像。

三、大一統的GOPATH

1、要理解三個環境變量

  • GOROOT:安裝GO的路徑,GOROOT下應該包含bin,src,pkg等文件夾。
  • GOPATH:用戶自己編的package的位置,GO語言要求所有與GO相關的代碼全部放在GOPATH下面,否則引用包會出錯的。GOPATH默認為${user.home}/go文件夾。
  • PATH:系統的環境變量,最好把$GOROOT/bin$GOPATH/bin添加到環境變量中。

Java的包管理有maven,不同項目之間共享代碼可以通過本地的mvn倉庫來實現。
Python的包管理有pip,需要什么包就安裝什么包,以包名為唯一標識符。
Node的包管理有npm,需要什么包全安裝到項目里面,不同項目之間不共享包。
Go的包管理方式可謂簡單粗暴,一切都得是源代碼,一切都得在GOPATH下面。

2、代碼組織

Go語言代碼組織比較奇葩,初入門時很難理解,建議讀一下官網文檔:https://golang.org/doc/code.html

  • Go programmers typically keep all their Go code in a single workspace.
    Go程序員通常把Go代碼放在一個文件夾(名叫workspace,工作空間)里面,而不是分散在好幾處
  • A workspace contains many version control repositories (managed by Git, for example).
    一個工作空間包含多個git倉庫
  • Each repository contains one or more packages.
    每一個git倉庫包含多個包
  • Each package consists of one or more Go source files in a single directory.
    每個包包含多個go源碼文件,這些文件都在同一個目錄下
  • The path to a package's directory determines its import path.
    包所在文件的路徑就是引入包時需要注明的路徑

工作空間中包含三個文件夾:

  • src contains Go source files,
  • pkg contains package objects, and
  • bin contains executable commands.

3、go install

首先創建一個文件夾,$ mkdir $GOPATH/src/github.com/user/hello,在這個文件夾下面編輯main.go

package main

import "fmt"

func main() {
	fmt.Printf("Hello, world.\n")
}

現在想把hello命令安裝到GOPATH/bin目錄下面,只需要 $ go install github.com/user/hello,或者cd到hello目錄下面,直接運行go install

四、GO沒有虛擬機如何垃圾回收

GO語言編譯之后生成的是可執行文件,不像Java生成的是字節碼。
Java的字節碼由Java虛擬機執行,垃圾回收當然就由虛擬機完成。
Go生成的是一個本地可執行文件,並且它包含垃圾回收,那么垃圾回收必然是打包在了exe里面的。
實際上,垃圾回收不一定非得由虛擬機來完成,Go生成的可執行文件中自動包含了垃圾回收部分的代碼,它會自動開辟一個線程專門進行垃圾回收。
那么,不同Go可執行程序之間是不共享垃圾回收模塊的,這樣就使得Go程序之間存在冗余(不過多占一點地方也不是問題)。

五、Go語言中的主函數

不像Java,類名跟文件名必須一致。Go語言中的文件名可以隨便寫,包名也不必考慮文件所在目錄(但是同一目錄下的文件包名必須一致)。但是Go語言中的主函數一定是main包下的main函數。

不同文件夾下的main.main函數互不影響。

Python和Java每一個文件都可以定義主函數,這就為快速測試提供了便利。Go和C、C++一樣,只能有一個main函數,正確姿勢是使用正經的測試而不是寫多個main函數。即便是Java和Python,使用main函數進行測試也不是好主意,

但是程序有多個入口這倒是一件非常方便的事情。Go其實也支持程序有多個入口,只需多寫幾個main函數就行了。

六、Go語言中的數據類型

1、布爾型
布爾型的值只可以是常量 true 或者 false。一個簡單的例子:var b bool = true。
2、數字類型
Go對數字類型的支持相當豐富,不像Java語言沒有無符號數字,不像Python那樣很裝逼的實現了長整數,不像C、C++里面int和long到底有多少位都說不清。Go語言明確支持四種數字類型:

  • uint:uint8,uint16,uint32,uint64
  • int:int8,int16,int32,int64
  • float:float32,float64(沒有double了)
  • complex:complex64(實部和虛部都是float32),complex128(實部和虛部都是float64)

3、字符串類型:
字符串就是一串固定長度的字符連接起來的字符序列。Go的字符串是由單個字節連接起來的。Go語言的字符串的字節使用UTF-8編碼標識Unicode文本。
4、派生類型:
包括:
(a) 指針類型(Pointer)
(b) 數組類型
(c) 結構化類型(struct)
(d) Channel 類型
(e) 函數類型
(f) 切片類型
(g) 接口類型(interface)
(h) Map 類型

Go語言的切片類型跟Python的切片類型不一樣,Go的切片是在原有數據上進行操作,而Python的切片類型是新復制了一份。

Go語言中沒有Object這樣的“萬物之祖”類型,而interface{}類型就是萬物之祖,也就是說:Go認為,不包含任何數據和方法的接口就是萬物之祖。

七、奇葩的錯誤處理

Go語言中允許函數返回多個參數,許多函數都會返回兩樣東西:正確答案和錯誤狀態。這一點跟C++、Java使用異常的機制完全不同,可以說Go語言里面根本不存在異常這種概念,因此你也不可能看見異常鏈(也就不可能像Java和Python那樣快速看到錯誤發生前發生的事情)。

參考資料

https://www.zhihu.com/question/58863427


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM