编程中级/主导 Go 开发者

关于 Go 中包 (packages) 的工作特性和可见性 (visibility) 的问题。何时以及如何使用导出对象和非导出对象?

用 Hintsage AI 助手通过面试

答案

在 Go 中,变量、函数、结构和方法的可见性与 首字母的大小写 紧密相关:

  • 名称以 大写字母 开头 — 对象会被导出到包之外。
  • 名称以 小写字母 开头 — 对象仅在其包内可用。

文件 example.go:

package mypkg var ExportedVar int // 其他包可用 var unexportedVar int // 仅在 mypkg 内可用

在导入包时,只能访问导出的对象。

最佳实践:

  • 隐藏实现细节,仅导出必要的类型和函数。
  • 对于私有常量/函数,使用小写名称。

变相问题

问题: “可以导出带有非导出字段的结构体吗?如果试图在其他包中使用这些字段会发生什么?”

答案: 仅以大写字母开头的结构体会被导出。 所有以小写字母开头的结构体字段在包外不可用。尝试从外部访问这些字段会导致编译错误。

示例:

// package user type User struct { Name string // 导出的字段 age int // 在 user 包外不可用 }

在另一个包中:

u := user.User{Name: "Ivan"} u.age = 42 // 编译错误:age is not accessible

真实错误示例


历史

JSON 序列化时数据丢失: 在 REST API 中导出了结构体,但字段设为非导出(小写字母)。结果,marshal 到 JSON 时未包含这些字段,API 用户未获得所需信息。


历史

无法访问所需函数: 团队将有用的工具移至单独的包,但忘记将其名称大写。函数无法访问,不得不重新设计接口。


历史

代码自动生成时命名冲突: 在一个包中生成代码时,使用了相同名称但字母大小写不同的变量。一个脚本错误地将导出的常量重命名为小写名称。结果,应用程序失去了对该常量的全局访问,部分功能变得不可用。