最近在配置 VSCode 的 Go 插件時,總是報錯找不到包之類的,發現時 GOPATH 和 GOROOT 在該編輯器中沒有配置,借此了解一下兩個環境變量。目前筆者用系統是 macOS BigSur,Go 版本 1.16.6
GOROOT
$GOROOT
,便是 Go 的安裝路徑,存放 Go 的內置程序庫。通常你安裝完后,你電腦的環境變量就會設好 GOROOT 路徑。當你開發 Go 程序的時候,當你 import 內置程序庫的時候,並不需要額外安裝,而當程序運行后, 默認也會先去 GOROOT 路徑下尋找相對應的庫來運行。
通過 go env
可以查看有關 Go 語言的相關環境變量設定。通常如果你是初次安裝 Go,並且沒做什么環境變量設定的話,GOROOT 設定路徑就是你當初安裝 Go 語言的路徑,通常類似於 /usr/local/go
、/usr/local/Cellar/go/1.xx.x/libexec
,一般為前者做軟連接到后者。而 GOPATH 通常默認會是用戶目錄下的 go 文件夾,通常類似於 $HOME/go
。
# vio1etus @ 192 in /usr/local/Cellar/go/1.16.6/libexec
$ tree ./ -L 1
./
├── CONTRIBUTING.md
├── CONTRIBUTORS
├── PATENTS
├── SECURITY.md
├── VERSION
├── api
├── bin
├── doc
├── favicon.ico
├── lib
├── misc
├── pkg
├── robots.txt
├── src
└── test
8 directories, 7 files
上述文件,有三點可了解:
bin 目錄:執行文件:go、gofmt,甚至 godoc
doc 目錄:Go 各個版本的文檔
src 目錄:go 標准庫源碼
GOPATH
Go 采用包管理,沒有項目的概念。Go工作區是Go管理我們的源文件、編譯的二進制文件和緩存對象的地方,緩存對象用於以后更快的編譯。雖然也可以有多個工作區,但通常建議只有一個。GOPATH 便充當工作區的根文件夾。
GOPATH,也叫工作區目錄(workspace directory),是Go代碼所在的目錄, Go 尋找 Go 工作區的位置。如果未設置環境變量,默認情況下,Go 假定我們的 GOPATH 位置在 $HOME/go
,其中 $HOME
是我們計算機上用戶帳戶的根目錄。 我們可以通過設置 $GOPATH 環境變量來改變它。 如需進一步學習,請按照本教程閱讀和設置 Linux 中的環境變量。 要檢查這一點,請輸入以下命令:go env GOPATH
$ go env GOPATH
/Users/vio1etus/go
一個 GOPATH 工作區,一般這樣:
./
├── bin
├── pkg
└── src
├── hello_github
└── hello_router.go
- bin:保存編譯后生成的可執行文件。我們的操作系統使用
$PATH
環境變量來查找無需完整路徑即可執行的二進制應用程序,建議將此目錄:$GOPATH/bin
添加到我們的全局$PATH
變量中。 - pkg:它保存已安裝的包對象(比如:.a)。每個目標操作系統和體系結構對都有自己的 pkg 子目錄。 Go 編譯包時生成的中間文件,用來緩存提高編譯效率。
- src:包含源代碼(比如:.go .c .h .s等)。 該路徑決定 import 包時的導入路徑或可執行文件名稱。
import包的搜索順序:- GOROOT/src:該目錄保存了Go標准庫代碼。
- GOPATH/src:該目錄保存了應用自身的代碼和第三方依賴的代碼。
GOROOT 和 GOPATH 配置
-
查看二者的環境變量
go env
查看 Go 相關全部環境變量
go env 變量名
,如:go env GOROOT
、go env GOPATH
等 -
配置 GOROOT
一般情況下 GOROOT 無需配置,但是如果你看到 GOROOT 為空,那可以:which go
查看 go 的位置$ go env GOROOT /usr/local/Cellar/go/1.16.6/libexec (base) # vio1etus @ 192 in ~/go/src [15:40:34] $ which go /usr/local/bin/go (base) # vio1etus @ 192 in ~/go/src [15:41:41] $ ll /usr/local/bin/go lrwxr-xr-x 1 vio1etus admin 26B Aug 8 21:08 /usr/local/bin/go -> ../Cellar/go/1.16.6/bin/go
- 設置環境變量
export GOROOT=/usr/local/bin/go
-
配置 GOPATH
- 在電腦上任意位置創建工作區目錄,例如:
~/GO_PROJECTS
- 設置環境變量
export GOPATH=~/GO_PROJECTS
- 在電腦上任意位置創建工作區目錄,例如:
go run、go build 和 go get
go run
go run,簡單理解就像是解釋的方式來執行代碼,而在細節上它其實會將代碼進行編譯,最后產生可執行文件,然后運行該可執行文件,產生程序執行后的結果,而可執行文件會放在特定的臨時文件里面,執行完就會自動刪除了。 通常開發上就是用於假設只是要測試一段代碼,那就會用go run來執行。
go build
go build
僅僅編譯以導入路徑命名的包及其依賴項,將其放到本地。通常在 $GOPATH 目錄下執行 go build,Go 會自動去src下尋找對應項目目錄,默認是在當前目錄下生成可執行文件。
go build 缺點:每次編譯代碼,比較沒有效率,當項目架構越來越大,build的速度也就越來越慢。
go install
因為 go build的缺點,因此有 go install 指令,go install 可以做兩件事情:
- 將包編譯成.a 中間緩存對象,如果源碼尚未更改,將在下一次編譯期間使用緩存。
- 如果是main包,並將其編譯成可執行文件
.
├── bin
│ └── hello # by go install
└── src
└── hello
├── hello # by go build
└── hello.go
注意:
- go install 如果要在非GOPATH路徑下使用的話,要先設定GOBIN環境變量,否則會出現錯誤
- 通常GOBIN環境變量就是設定GOPATH/bin。
go get(deprecated in go1.16)
GOPATH 很大的缺點,就是相關第三方包只要不是官方庫,都需要放置在GOPATH/src的路徑下才可使用。通常我們會使用go get指令來獲取網絡上的第三方包,並安裝到本地,例如:
go get github.com/gin-gonic/gin
當我們從Github 上下載第三方包多了之后,會發現 GOPATH/src 下的代碼會很復雜,除了有你自己開發的項目文件夾,也包含其他第三方庫的項目文件夾。
此外,如果你開發的項目采用第三方套件是不同版本也很棘手。以往的解決方法是要設定多組不同的GOPATH。 雖然社群也有開發相對應的 package manager,如 Vendor、Dep 來解決該問題,但畢竟不是官方主導的。因此,有了 Go Modules 的誕生,我們下一篇文章再講。
但是從 Go 1.16 開始逐漸廢棄 go get 安裝包的功能,詳細見New module changes in Go 1.16 - go.dev,官方推薦使用 go install 帶版本安裝, 使用示例:
go install golang.org/x/tools/gopls@latest
go install golang.org/x/tools/gopls@v0.6.5