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

3 回复

好的,我一直以为如果一个结构体是公开的,那么它的字段也会是公开的。真是每天都能学到新东西 🙂

更多关于Golang中为什么无法访问返回结构体的字段?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


@Pisistrato 公共字段的名称应以大写字母开头。

以 Unicode 大写字母开头的标识符称为 导出标识符。在许多其他语言中,导出一词可以理解为 公共。不以 Unicode 大写字母开头的标识符称为非导出标识符。在许多其他语言中,非导出一词可以理解为 私有

来源: Go 101 网站图标

Go 中的关键字和标识符 - Go 101

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 字段,并通过其他导出的接口提供了访问数据的方式。你需要查看包的文档或导出方法列表来找到正确的访问方式。

回到顶部