英文:
exposing a private type through a public function
问题
我正在测试Go语言的类型可见性,并在通过公共函数公开私有类型时遇到了意外的行为:
package pak
type foo struct { // 不应该对除了pak之外的任何其他包可见
Bar string
}
func NewFoo(str string) *foo {
return &foo{Bar: str}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package main
import (
"fmt"
"pak"
)
func main() {
// 这两行应该是等价的...
var f = pak.NewFoo("Hello, World!") // 这个可以正常工作...
var f *pak.foo = pak.NewFoo("Hello, World!") // 错误:无法引用未导出的名称pak.foo
fmt.Printf("%T\n", f)
fmt.Printf("%s\n", f.Bar) // 如果它看不到pak.foo,它是如何知道.Bar的存在的?
}
在没有显式声明f的类型时,它打印出:
*pak.foo
Hello, World!
但是使用*pak.foo时,它无法编译通过。
为什么两种情况下都没有失败?
英文:
I was testing go's type visibility and received unexpected behavior when I exposed a private type through a public function:
package pak
type foo struct { // shoudn't be visible to any other package than pak
Bar string
}
func NewFoo(str string) *foo {
return &foo{str}
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
package main
import (
"fmt"
"pak"
)
func main() {
// these lines should be equivalent...
var f = pak.NewFoo("Hello, World!") // this works fine...
var f *pak.foo = pak.NewFoo("Hello, World!") // ERROR: cannot refer to unexported name pak.foo
fmt.Printf("%T\n", f)
fmt.Printf("%s\n", f.Bar) // how does it know about .Bar, if it can't see pak.foo?
}
Without explicitly declaring the type of f, it prints:
*pak.foo
Hello, World!
but with *pak.foo it fails to compile.
Why doesn't it fail in both cases?
(this question is sort of related, but it does not answer this question)
答案1
得分: 3
有效的语句
var f = pak.NewFoo("test")
为struct foo提供了一个匿名的、隐藏的地址。你不能在pak包之外使用它来读取或写入struct foo。你可以使用它来调用pak包的方法。例如,
p := f.PakMethod()
无效的语句
var f *pak.foo = pak.NewFoo("test")
试图获取struct foo的地址。如果允许,这将允许你在pak包之外读取和写入struct foo。
英文:
The valid statement
var f = pak.NewFoo("test")
gives you an anonymous, hidden address for the struct foo. You can't use it to read from or write to the struct foo outside the pak package. You can, and usually will, use it to call a pak package method. For example,
p := f.PakMethod()
The invalid statement
var f *pak.foo = pak.NewFoo("test")
attempts to obtain the address of the struct foo. If permitted, this would allow you to read from and write to the struct foo outside the pak package.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论