Golang中为什么无法访问返回结构体的字段?
Golang中为什么无法访问返回结构体的字段? 这是一个非常愚蠢的问题,但我就是想不明白。
我正在尝试使用一个旧包来完成一个非常简单的任务。
这个包是 bitbucket.org/proteinspector/ms/unthermo。
我需要做的就是使用 unthermo.Open 来读取一个特定文件并从中获取一些信息。
现在,当我查看 unthermo 的源代码时,我可以看到 Open 是这样实现的:
func Open(fn string) (file File, err error) {
f, err := os.Open(fn)
// 更多代码...
// 我现在需要的信息
scanindex := make(ScanIndex, nScans)
readBetween(f, rh.ScanindexAddr, rh.ScantrailerAddr, ver, scanindex)
// 更多代码...
return File{f: f, scanevents: scanevents, scanindex: scanindex}, err
}
然而,在我的应用程序中,我无法访问字段 scanindex。
func main() {
// 打开文件
file, _ := unthermo.Open("somefile")
defer file.Close()
// 这无法编译
info := file.scanindex
fmt.Println(info)
}
为什么?
更多关于Golang中为什么无法访问返回结构体的字段?的实战教程也可以访问 https://www.itying.com/category-94-b0.html
好的,我一直以为如果一个结构体是公开的,那么它的字段也会是公开的。真是每天都能学到新东西 🙂
更多关于Golang中为什么无法访问返回结构体的字段?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
嗨 @Pisistrato 公共字段的名称应以大写字母开头。
以 Unicode 大写字母开头的标识符称为 导出标识符。在许多其他语言中,导出一词可以理解为 公共。不以 Unicode 大写字母开头的标识符称为非导出标识符。在许多其他语言中,非导出一词可以理解为 私有。
来源:
Golang 在线书籍、文章、工具等。
这是因为 scanindex 字段在 unthermo.File 结构体中是未导出的(小写字母开头)。在 Go 语言中,只有首字母大写的标识符(字段、方法、函数、类型等)才能被包外部的代码访问。
查看 unthermo 包的源代码,File 结构体可能类似这样:
type File struct {
f *os.File // 未导出字段
scanevents []ScanEvent // 未导出字段
scanindex ScanIndex // 未导出字段 - 这就是你无法访问的原因
}
要解决这个问题,你有几个选择:
1. 使用包提供的导出方法 通常这类库会提供访问器方法:
func main() {
file, err := unthermo.Open("somefile")
if err != nil {
log.Fatal(err)
}
defer file.Close()
// 检查包是否有类似这样的导出方法
// scanindex := file.GetScanIndex()
// 或者
// scanindex := file.ScanIndex()
}
2. 查看包的导出函数 有时相关信息会通过独立的函数提供:
func main() {
file, _ := unthermo.Open("somefile")
defer file.Close()
// 检查包是否有类似这样的函数
// scanindex := unthermo.GetScanIndex(file)
}
3. 如果必须直接访问,可以修改本地副本(不推荐) 创建一个本地副本并导出字段:
// 在你的代码中重新定义结构体
type MyFile struct {
F *os.File
Scanevents []unthermo.ScanEvent
Scanindex unthermo.ScanIndex
}
func convertFile(f unthermo.File) MyFile {
// 使用反射或其他方法复制字段
// 注意:这需要 unthermo.ScanIndex 类型是导出的
}
4. 查看包文档或源代码中的其他接口 通常这类数据会通过其他方式暴露:
func main() {
file, _ := unthermo.Open("somefile")
defer file.Close()
// 可能通过迭代器或扫描方法访问
for i := 0; i < file.NumScans(); i++ {
scan := file.Scan(i)
// 处理扫描数据
}
}
最可能的情况是,这个包的设计者有意隐藏了 scanindex 字段,并通过其他导出的接口提供了访问数据的方式。你需要查看包的文档或导出方法列表来找到正确的访问方式。

