这样想:
package first
type person struct {
Name string
}
var Per = person{
Name: "Jack",
}
并在主程序包中
package main
import "first"
import "fmt"
func main(){
o := first.Per
fmt.Println(o)
}
上面的工作,我们可以看到第一个包中的变量在外面是可见的,但它的类型不是,但它没有给出错误?以及如何在包装外使用它?
答案 0 :(得分:3)
没关系:
导出的标识符:
可以导出标识符以允许从另一个标识符访问它 包。如果两者都导出标识符:
- 标识符名称的第一个字符是Unicode大写 字母(Unicode类“Lu”);和
- 标识符在。中声明 包块或它是字段名称或方法名称。所有其他 标识符不会导出。
参考:https://golang.org/ref/spec
甚至你可以使用Getters:
Go不为getter和setter提供自动支持。有 自己提供吸气剂和制定者并没有错,而且确实如此 通常适合这样做,但它既不是惯用的,也不是必需的 将Get放入getter的名字。如果您有一个名为owner的字段 (小写,未导出),getter方法应该称为Owner (大写,导出),而不是GetOwner。使用大写名称 export提供了用于区分字段和方法的钩子。一个 如果需要,setter函数可能会被称为SetOwner。两个名字 在实践中读得很好:
owner := obj.Owner() if owner != user { obj.SetOwner(user) }
参考:https://golang.org/doc/effective_go.html
所以,如果您不想导出Name
,请将其设为小写,例如此工作示例代码并使用Getter / Setter:
package first
type person struct {
name string
}
var Per = person{
name: "Jack",
}
func (p *person) SetName(name string) {
p.name = name
}
func (p *person) Name() string {
return p.name
}
main.go(带注释输出):
package main
import "first"
import "fmt"
func main() {
person := first.Per
fmt.Println(person.Name()) //Jack
person.SetName("Alex")
fmt.Println(person.Name()) //Alex
}
答案 1 :(得分:1)
基本上,它是单身人士模式。该软件包导出person
的单个实例,但由于该类型是私有的,因此您无法创建另一个实例。
更好的实现是导出一个返回私有类型的单例实例的函数。在第一次调用时,它将以线程安全的方式创建实例。
var (
p *person
once sync.Once
)
type person struct {
Name string
}
func Per() *person {
once.Do(func() {
p = &person{
Name: "Jack",
}
})
return p
}
sync.Once
允许您只执行一段代码,即使多个goroutine正在尝试执行它。