当我通过公共函数公开私有类型时,我正在测试go的类型可见性并收到意外行为:
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?
}
如果没有明确声明f
的类型,则会打印:
*pak.foo
Hello, World!
但是*pak.foo
无法编译。
为什么两种情况都不会失败?
(这个question有点相关,但它没有回答这个问题)
答案 0 :(得分:3)
有效声明
var f = pak.NewFoo("test")
为您提供struct
foo
的匿名隐藏地址。您无法使用它来读取或写入struct
包之外的foo
pak
。您可以(通常会)使用它来调用pak
包方法。例如,
p := f.PakMethod()
无效陈述
var f *pak.foo = pak.NewFoo("test")
尝试获取struct
foo
的地址。如果允许,这样您就可以在struct
包裹之外阅读并写信foo
pak
。