引言
熟悉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包的作用和使用场景,一定要亲手写代码体会一下其使用方法和使用场景。