Golang中为什么非内部包可以暴露内部实现?
Golang中为什么非内部包可以暴露内部实现? 在一个包含内部包和非内部包的Go模块中,非内部包可以暴露内部包的内容,例如内部包的结构体。当我遇到这种行为时,我原以为这是一个bug,但在cmd/go: Contents of internal package can be exposed through non-internal package · Issue #71894 · golang/go · GitHub中被确认这是有意为之的。
下面是一个例子,其中非内部函数 Foo 可以暴露内部结构体 Bar:
$ cat foo/internal/bar/bar.go
package bar
type Bar struct {
X int
}
$ cat foo/foo.go
package foo
import "foo/internal/bar"
func Foo() bar.Bar {
return bar.Bar{X: 42}
}
当在另一个Go模块中使用 Foo 的返回值时,编译器对此没有报错。为什么会这样?这是否属于Go作者为我们提供的“一把锋利的刀”用于特殊情况,并假设我们开发者知道不去滥用它的情况之一?
更多关于Golang中为什么非内部包可以暴露内部实现?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
嗯,我还没从这个角度考虑过,感谢提供示例。
更多关于Golang中为什么非内部包可以暴露内部实现?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
Go 有一个模型,即所有以大写字母开头的内容都会被导出。无论你是否将你的包命名为 internal。如果你不想让其他人访问内部实现,只保留 API 并将所有内容设为非导出即可。
你的问题很奇怪,这类似于:
type b struct {
}
func FuncA() *b {
return &b{}
}
不要局限于特性。闭包只是为了将某些东西隔离起来,使其不能被外部调用,但这并不意味着被抛出的东西不能被使用。
我不明白。一个没有任何导出的内部包是完全无用的,因为无法与之交互。
你是否知道,internal 在包路径中具有特殊含义?请参阅 go 命令 - cmd/go - Go 包
是的,我知道。我想你需要再读一遍这篇文章。它明确指出,internal 目录下的包可以被任何根目录位于该 internal 目录之上的包导入。在你的示例中,你正是这样做的。这意味着,如果你 internal 目录下的内容是导出的,那么你就可以访问它们。即使在 GitHub 的 issue 里,也有很多关于 internal 名称误解的讨论链接。cmd/go: modules: exposure of internal packages · Issue #30569 · golang/go · GitHub
抱歉,我想我们一开始就有些误会。我很清楚 foo 包应该能够使用 foo/internal/bar 包。这是设计如此,工作正常。
让我感到惊讶的是,我竟然能够在另一个 Go 模块中使用 foo 模块的内部包的 Bar 结构体。例如,在一个不同的 Go 模块中,我能够访问这个内部结构体的字段:
$ cat baz/baz.go
package main
import "fmt"
import "foo"
func main() {
fmt.Println(foo.Foo().X)
}
$ cd baz && go run .
42


