天天看點

工作區和GOPATH

在過去的幾年裡,我與廣大愛好者一起見證了 Go 語言的崛起。

從 Go 1.5 版本的自舉(即用 Go 語言編寫程式來實作 Go 語言自身),到 Go 1.7 版本的極速 GC(也稱垃圾回收器),再到 2018 年 2 月釋出的 Go 1.10 版本對其自帶工具的全面更新,以及可預見的後續版本關鍵特性(比如用來做程式依賴管理的​

​go mod​

​指令),這一切都令我們歡欣鼓舞。Go 語言在一步步走向輝煌的同時,顯然已經成為軟體工程師們最喜愛的程式設計語言之一。

我開辦這個專欄的主要目的,是要與你一起探索 Go 語言的奧秘,并幫助你在學習和實踐的過程中擷取更多。

我假設本專欄的讀者已經具備了一定的計算機基礎,比如,你要知道作業系統是什麼、環境變量怎麼設定、怎樣正确使用指令行,等等。

當然了,如果你已經有了程式設計經驗,尤其是一點點 Go 語言程式設計經驗,那就更好了,畢竟我想教給你的,都是 Go 語言中非常核心的技術。

如果你對 Go 語言中最基本的概念和文法還不夠了解,那麼可能需要在學習本專欄的過程中去查閱​​Go 語言規範文檔​​,也可以把預習篇的基礎知識圖拿出來好好研究一下。

最後,我來說一下專欄的講述模式。我總會以一道 Go 語言的面試題開始,針對它進行解答,我會告訴你為什麼我要關注這道題,這道題的背後隐藏着哪些知識,并且,我會對這部分的内容,進行相關的知識擴充。

好了,準備就緒,我們一起開始。

我們學習 Go 語言時,要做的第一件事,都是根據自己電腦的計算架構(比如,是 32 位的計算機還是 64 位的計算機)以及作業系統(比如,是 Windows 還是 Linux),從​​Go 語言官網​​下載下傳對應的二進制包,也就是可以拿來即用的安裝包。

随後,我們會解壓縮安裝包、放置到某個目錄、配置環境變量,并通過在指令行中輸入​

​go version​

​來驗證是否安裝成功。

在這個過程中,我們還需要配置 3 個環境變量,也就是 GOROOT、GOPATH 和 GOBIN。這裡我可以簡單介紹一下。

  • GOROOT:Go 語言安裝根目錄的路徑,也就是 GO 語言的安裝路徑。
  • GOPATH:若幹工作區目錄的路徑。是我們自己定義的工作空間。
  • GOBIN:GO 程式生成的可執行檔案(executable file)的路徑。

其中,GOPATH 背後的概念是最多的,也是最重要的。那麼,今天我們的面試問題是:你知道設定 GOPATH 有什麼意義嗎?

關于這個問題,它的典型回答是這樣的:

你可以把 GOPATH 簡單了解成 Go 語言的工作目錄,它的值是一個目錄的路徑,也可以是多個目錄路徑,每個目錄都代表 Go 語言的一個工作區(workspace)。

我們需要利于這些工作區,去放置 Go 語言的源碼檔案(source file),以及安裝(install)後的歸檔檔案(archive file,也就是以“.a”為擴充名的檔案)和可執行檔案(executable file)。

事實上,由于 Go 語言項目在其生命周期内的所有操作(編碼、依賴管理、建構、測試、安裝等)基本上都是圍繞着 GOPATH 和工作區進行的。是以,它的背後至少有 3 個知識點,分别是:

1. Go 語言源碼的組織方式是怎樣的;

2. 你是否了解源碼安裝後的結果(隻有在安裝後,Go 語言源碼才能被我們或其他代碼使用);

3. 你是否了解建構和安裝 Go 程式的過程(這在開發程式以及查找程式問題的時候都很有用,否則你很可能會走彎路)。

下面我就重點來聊一聊這些内容。

知識擴充

1. Go 語言源碼的組織方式

與許多程式設計語言一樣,Go 語言的源碼也是以代碼包為基本組織機關的。在檔案系統中,這些代碼包其實是與目錄一一對應的。由于目錄可以有子目錄,是以代碼包也可以有子包。

一個代碼包中可以包含任意個以.go 為擴充名的源碼檔案,這些源碼檔案都需要被聲明屬于同一個代碼包。

代碼包的名稱一般會與源碼檔案所在的目錄同名。如果不同名,那麼在建構、安裝的過程中會以代碼包名稱為準。

每個代碼包都會有導入路徑。代碼包的導入路徑是其他代碼在使用該包中的程式實體時,需要引入的路徑。在實際使用程式實體之前,我們必須先導入其所在的代碼包。具體的方式就是​

​import​

​該代碼包的導入路徑。就像這樣:

import "github.com/labstack/echo"      

在工作區中,一個代碼包的導入路徑實際上就是從 src 子目錄,到該包的實際存儲位置的相對路徑。

是以說,Go 語言源碼的組織方式就是以環境變量 GOPATH、工作區、src 目錄和代碼包為主線的。一般情況下,Go 語言的源碼檔案都需要被存放在環境變量 GOPATH 包含的某個工作區(目錄)中的 src 目錄下的某個代碼包(目錄)中。

2. 了解源碼安裝後的結果

了解了 Go 語言源碼的組織方式後,我們很有必要知道 Go 語言源碼在安裝後會産生怎樣的結果。

源碼檔案以及安裝後的結果檔案都會放到哪裡呢?我們都知道,源碼檔案通常會被放在某個工作區的 src 子目錄下。

那麼在安裝後如果産生了歸檔檔案(以“.a”為擴充名的檔案),就會放進該工作區的 pkg 子目錄;如果産生了可執行檔案,就可能會放進該工作區的 bin 子目錄。

我再講一下歸檔檔案存放的具體位置和規則。

源碼檔案會以代碼包的形式組織起來,一個代碼包其實就對應一個目錄。安裝某個代碼包而産生的歸檔檔案是與這個代碼包同名的。

放置它的相對目錄就是該代碼包的導入路徑的直接父級。比如,一個已存在的代碼包的導入路徑是

github.com/labstack/echo,      

那麼執行指令

go install github.com/labstack/echo      

生成的歸檔檔案的相對目錄就是 ​​github.com/labstack,​​ 檔案名為 echo.a。

順便說一下,上面這個代碼包導入路徑還有另外一層含義,那就是:該代碼包的源碼檔案存在于 GitHub 網站的 labstack 組的代碼倉庫 echo 中。

再說回來,歸檔檔案的相對目錄與 pkg 目錄之間還有一級目錄,叫做平台相關目錄。平台相關目錄的名稱是由 build(也稱“建構”)的目标作業系統、下劃線和目标計算架構的代号組成的。

比如,建構某個代碼包時的目标作業系統是 Linux,目标計算架構是 64 位的,那麼對應的平台相關目錄就是 linux_amd64。

是以,上述代碼包的歸檔檔案就會被放置在目前工作區的子目錄 pkg/linux_amd64/github.com/labstack 中。

工作區和GOPATH

(GOPATH 與工作區)

總之,你需要記住的是,某個工作區的 src 子目錄下的源碼檔案在安裝後一般會被放置到目前工作區的 pkg 子目錄下對應的目錄中,或者被直接放置到該工作區的 bin 子目錄中。

3. 了解建構和安裝 Go 程式的過程

我們再來說說建構和安裝 Go 程式的過程都是怎樣的,以及它們的異同點。

建構使用指令​

​go build​

​​,安裝使用指令​

​go install​

​。建構和安裝代碼包的時候都會執行編譯、打包等操作,并且,這些操作生成的任何檔案都會先被儲存到某個臨時的目錄中。

如果建構的是庫源碼檔案,那麼操作的結果檔案隻會存在于臨時目錄中。這裡的建構的主要意義在于檢查和驗證。

如果建構的是指令源碼檔案,那麼操作的結果檔案會被搬運到源碼檔案所在的目錄中。

安裝操作會先執行建構,然後還會進行連結操作,并且把結果檔案搬運到指定目錄。進一步說,如果安裝的是庫源碼檔案,那麼結果檔案會被搬運到它所在工作區的 pkg 目錄下的某個子目錄中。

如果安裝的是指令源碼檔案,那麼結果檔案會被搬運到它所在工作區的 bin 目錄中,或者環境變量​

​GOBIN​

​指向的目錄中。

這裡你需要記住的是,建構和安裝的不同之處,以及執行相應指令後得到的結果檔案都會出現在哪裡。

總結

繼續閱讀