
在 Go 语言中,结构体字段首字母大写(如 Name)才可被其他包导出并访问;小写字段(如 name)为未导出(私有),外部包无法直接读写。这是 Go 的可见性规则,而非访问权限控制机制。
在 go 语言中,结构体字段首字母大写(如 `name`)才可被其他包导出并访问;小写字段(如 `name`)为未导出(私有),外部包无法直接读写。这是 go 的可见性规则,而非访问权限控制机制。
Go 采用标识符首字母大小写来决定其导出性(exportedness):只有首字母大写的类型、函数、变量和结构体字段才能被其他包访问。这与传统面向对象语言中的 public/private 关键字不同——Go 没有访问修饰符,而是通过命名约定强制实现封装。
例如,您定义的 Student 结构体若希望被 main 包安全使用,必须将字段声明为导出字段:
// models/student.go
package models
type Student struct {
Name string // ✅ 导出字段:可被其他包访问
Number int // ✅ 导出字段
}随后在 main 包中即可正常赋值与使用:
// main.go
package main
import (
"fmt"
"github.com/nikolastankovic/hello/models"
)
func main() {
var nikola models.Student
nikola.Name = "nikola" // ✅ 正确:字段首字母大写,可导出
nikola.Number = 12345 // ✅ 同理
fmt.Printf("%+v\n", nikola) // 输出:{Name:"nikola" Number:12345}
}⚠️ 注意事项:
- 字段名
name(小写)在 Go 中属于未导出字段,即使在同一包内也不影响;但一旦跨包(如main调用models),编译器会直接报错:cannot refer to unexported field 'name' in struct literal of type models.Student。 - 导出性仅取决于名称拼写,与结构体是否为
public类型无关;只要结构体本身导出(如Student首字母大写),其导出字段即可被外部包使用。 - 若需封装敏感字段(如密码、内部状态),应结合构造函数与getter/setter 方法(虽非强制,但属最佳实践)。例如:
// models/student.go
func NewStudent(name string, number int) *Student {
return &Student{Name: name, Number: number}
}
// 可选:提供只读访问或受控修改逻辑
func (s *Student) GetName() string { return s.Name }总结:Go 的“包级封装”由标识符命名驱动——牢记 “首字母大写即导出,小写即包内私有”。将模型拆分为独立包(如 models)是良好工程实践,只需确保结构体及其关键字段按此规则命名,即可安全、清晰地实现模块化设计。

















