Skip to content

internal 目录的奥妙

Go 编译器对 internal/ 这个目录名做了特殊处理:

myapp/
├── go.mod                       (module github.com/me/myapp)
├── cmd/server/main.go           ✅ 可以 import internal/foo
├── internal/foo/foo.go          ← 内部包
└── pkg/utils/utils.go           ✅ 可以 import internal/foo

外部项目 otherapp/
└── 不能 import github.com/me/myapp/internal/foo  ❌

规则

internal/ 内的包,只能被该 internal 目录的父目录及其子目录里的代码 import

这是 Go 内置的"包级私有化"机制,比注释里写"please don't use" 靠谱多了。


实测代码

internal/secret/secret.go

go
package secret

func Token() string { return "super-secret" }

cmd/main.go

go
import "github.com/me/myapp/internal/secret"
func main() { fmt.Println(secret.Token()) }   // ✅ OK

如果别的项目 import:

package github.com/me/myapp/cmd
        imports github.com/me/myapp/internal/secret:
        use of internal package github.com/me/myapp/internal/secret not allowed