Golang模塊級私有包(Internal Package Mechanism)詳解
引言
熟悉Golang的同學應該都知道Golang的包機制,一個包中的程序實體有兩種訪問權限:可導出(其他包可以訪問)和不可導出(其他包不能訪問,包內可訪問)。
但是這兩種訪問權限并不能滿足所有的場景,例如組織WEB項目目錄結構的場景。組織WEB項目目錄結構的典型場景如下:一般把項目中處理業務邏輯的部分放在一起(分為三層,分別是接口表示層(api)、業務邏輯層(bll),數據訪問層(dal)),不希望其他部分代碼訪問業務邏輯部分的代碼,而允許業務邏輯部分代碼訪問其他部分代碼,這樣嚴格分為業務邏輯部分和非業務邏輯部分,結構清晰,方便維護。要從根本上防止其他部分代碼不能訪問業務邏輯部分的代碼一般語言都沒有提供這種機制,Golang從1.4引入的內部包機制(將包命名為internal)就可以實現這一點。
什么是內部包(Internal packages)?
內部包就是將代碼放在名為internal的目錄或名為internal的目錄的子目錄中。有以下特點:
- /a/b/c/internal/d/e/f目錄中的代碼只能被/a/b/c目錄中代碼(文件或子目錄中代碼)導入,而不能被/a/b/g目錄下的代碼導入;
- $GOROOT/src/pkg/internal/xxx只能被$GOROOT/src/目錄中代碼導入(文件或子目錄中代碼);
- $GOROOT/src/pkg/net/http/internal只能被net/http和net/http/* 導入;
- $GOPATH/src/mypkg/internal/foo只能被$GOPATH/src/mypkg目錄中的代碼導入(文件或子目錄中代碼)。
示例說明
以如下目錄結構為例說明:
├── pkg1
│ ├── internal
│ │ ├── sub2
│ │ └── sub2.go
│ │ └── test1.go
│ │
│ ├── sub1
│ │ └── test2.go
│ └── pkg1.go
├── pkg2
│ └── pkg2.go
└── main.go
可以導入internal包的代碼:test2.go、pkg1.go和sub2.go,不能導入internal包的代碼:main.go和pkg2.go。
可以導入sub2包的代碼:test2.go、pkg1.go和test1.go,不能導入sub2包的代碼:main.go和pkg2.go。
小結
本文介紹了internal包的作用和使用場景,一定要親手寫代碼體會一下其使用方法和使用場景。