Golang中为什么非内部包可以暴露内部实现?
Golang中为什么非内部包可以暴露内部实现? 我发现了一个奇怪的行为,不确定这是否是一个错误。在向 GitHub - golang/go: The Go 编程语言 提交问题之前,我想听听你们是否认为这是一个错误。假设我的模块中有两个包:
foo/internal/bar:此包导出了type MyBar struct {...}foo:此包导入了foo/internal/bar并定义了func Foo() bar.MyBar {...}
在这种“包布局”下,go vet 没有任何报错。我也可以从另一个模块使用 Foo 函数,例如,打印其返回值。我认为不应该允许从一个非内部函数返回一个内部结构体,因为这规避了内部结构体通常的限制。
你们是否也认为这是一个错误,或者当前的行为有什么合理的理由?
更多关于Golang中为什么非内部包可以暴露内部实现?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
这是一个符合 Go 语言设计的行为,不是错误。internal 目录的访问限制是基于导入路径的,而不是基于类型的可见性。
当你在 foo 包中导入 foo/internal/bar 时,这是被允许的,因为 foo 和 foo/internal/bar 在同一个模块内(共享 foo 前缀)。internal 的限制只适用于模块外部的包。
示例代码:
// foo/internal/bar/bar.go
package bar
type MyBar struct {
Value string
}
// foo/foo.go
package foo
import "foo/internal/bar"
func Foo() bar.MyBar {
return bar.MyBar{Value: "internal"}
}
// 其他模块可以这样使用
package main
import (
"fmt"
"foo"
)
func main() {
b := foo.Foo()
fmt.Println(b.Value) // 输出: internal
}
go vet 不会报错是因为这种用法完全符合 Go 的语言规范。internal 机制的目的是防止模块外部的代码直接导入内部包,而不是限制内部类型在模块内部的传播。一旦 foo 包导出了返回 bar.MyBar 的函数,这个类型就通过 foo 包的公共 API 暴露给了外部调用者。
这种设计允许模块内部有更灵活的组织结构,同时仍然通过 internal 目录保护了实现细节不被外部直接导入。


