英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论