
在 go 中,只有首字母大写的结构体字段才是导出(public)的,才能被其他包访问;小写字母开头的字段为未导出(private),仅限本包内使用。这是 go 的基础可见性机制,直接影响跨包模型字段的读写。
在 go 中,只有首字母大写的结构体字段才是导出(public)的,才能被其他包访问;小写字母开头的字段为未导出(private),仅限本包内使用。这是 go 的基础可见性机制,直接影响跨包模型字段的读写。
Go 语言通过标识符的首字母大小写严格控制作用域和可见性——这与多数面向对象语言的 public/private 关键字不同,是 Go 独特的“导出规则”(Export Rule)。当你将模型(如 Student)定义在独立包(如 github.com/nikolastankovic/hello/models)中,并希望在 main 包中访问其字段时,必须确保字段名以大写字母开头。
✅ 正确做法:将字段 name 改为 Name,number 改为 Number:
// 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" // ✅ 合法:Name 是导出字段
nikola.Number = 12345 // ✅ 合法:Number 是导出字段
fmt.Printf("Student: %+v\n", nikola) // 输出:Student: {Name:"Nikola" Number:12345}
}
⚠️ 注意事项:
- 字段名
name(小写)在models包外完全不可见,编译器会报错:cannot refer to unexported field name in models.Student; - 不仅字段,函数、类型、常量等所有标识符均遵循同一规则:首字母大写 → 可导出 → 跨包可用;
- 导出字段仍需遵循 Go 的封装原则:若需校验或逻辑控制,建议配合构造函数(如
NewStudent())和 Getter/Setter 方法(注意:Go 无传统 setter 语法,通常用普通方法实现); - 模型包设计建议:将
models作为纯数据载体,避免在其中嵌入业务逻辑;复杂行为宜放在 service 或 domain 层。
总结:Go 的可见性由命名决定,而非修饰符。将模型拆分为独立包是良好实践,但务必遵守导出规则——让字段“走出去”的第一步,就是给它一个大写的开头。










