go通过首字母大小写严格控制结构体字段的包级可见性:大写字母开头的字段可被其他包访问(导出),小写字母开头的字段仅限本包内使用(非导出),这是go封装机制的核心设计。
在Go语言中,结构体字段的可访问性并非由private或public关键字决定,而是完全依赖标识符的命名规则。这一设计简洁而有力,是Go“显式优于隐式”哲学的典型体现。
字段导出规则:唯一且明确
根据Go语言规范,一个结构体字段要能被其他包访问(即“导出”),必须同时满足两个条件:
- 字段名以Unicode大写字母(如A–Z)开头;
- 该字段定义在包级别(即属于某个结构体类型,而非局部作用域)。
例如,以下结构体中只有R、X、Y是导出字段,r、x、y则为非导出字段:
type Circle struct {
X, Y float64 // ✅ 导出:可被其他包读写
R float64 // ✅ 导出
x, y float64 // ❌ 非导出:仅限本包内访问
r float64 // ❌ 非导出
}
因此,您最初示例能成功运行,正是因为所有字段(x, y, r)均定义在main包内——同一包内可自由访问非导出字段;但一旦将Circle移入独立包(如geom),外部包尝试访问c.r就会触发编译错误:cannot refer to unexported field r in struct literal of type geom.Circle。