go build尋找import的包過程(1.14版本開啓go mod)

今天在看一個程序代碼,發現裏面用到了grpc,程序的目錄結構是這樣的

onlineClean 包名main
main.go
go.mod
proto
structs.go 包名proto
rpcClient 包名main
test.go

其中rpcCleint/test.go裏面有這樣的代碼

import (
	"fmt"

	pb "onlineClean/proto"

	"golang.org/x/net/context"

	"google.golang.org/grpc"
)

當時我覺得有點奇怪,在rpcClient裏面這樣引用onlineClean/proto,可以編譯過嗎?

於是試驗了一下,在rpcCleint下執行go build(go 版本是1.14),發現還真可以編譯成功。

當時我就在想,go build尋找import的包過程是怎麼樣的呢? 它是怎麼發現onlineClean/proto這個包的

很明顯,這裏go build時應該是從rpcClient的上層目錄開始找onlineClean/proto的,那爲啥它是從上層目錄找而不是當前目錄找呢?

上網找了一下,網上文章是這樣說的:

在我們引入第三方的時候,其會在三個地方區查找
1、GOROOT路徑
2、GOPATH路徑
3、在原目錄中的vendor目錄下進行查找

裏面沒提到會從上級目錄找。

我檢查了一下GOROOT和GOPATH變量(go env GOROOT和go env GOPATH),發現都沒有包含onlineClean或者../目錄

感覺網上說的可能不太全,或者網上的資料太舊了,不適合1.14

後來,偶然間,我發現把rpcClient複製到其它目錄(與onlineClean並列),就編譯不了。編譯提示“go: cannot find main module; see 'go help modules'”

然後我對比了在onlineClean/rpcClient和rpcClient兩個目錄執行go env的區別,發現主要是GOMOD環境變量的區別:

在onlineClean/rpcClient,會輸出set GOMOD=D:\ht\軟件部\數據質量管控平臺\代碼\華爲雲\go\onlineClean\go.mod

而在rpcClient則沒有輸出這個環境變量。

於是我猜測,開啓go mod時go build時會向上找go.mod,找到後使用這個go.mod進行第三方包管理,查了一下go mod的幫助文檔,證實了我這個猜測。

go helo go.mod

A module version is defined by a tree of source files, with a go.mod
file in its root. When the go command is run, it looks in the current
directory and then successive parent directories to find the go.mod
marking the root of the main (current) module.

這段話大概是說:當go命令運行,會先查找當前目錄有沒有go.mod,如果沒有會一直向上找,直到找到go.mod,並以找到go.mod的目錄做爲根目錄進行第三方包引用 。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章