
ioutil.ReadDir 返回的 os.FileInfo 切片中,Name 是一个方法而非字段,直接打印 element.Name 会输出函数地址;必须调用 element.Name() 才能获取实际文件名字符串。
go 中正确获取文件名:fileinfo.name() 方法调用详解
在 Go 文件系统操作中,ioutil.ReadDir(现已推荐替换为 os.ReadDir,但接口兼容)返回的是 []os.FileInfo 类型切片,其中每个元素实现了 os.FileInfo 接口。值得注意的是:Name 并非结构体字段,而是一个无参方法(签名:func() string)。因此,element.Name 表示该方法的值(即函数指针),而非执行结果——这正是你看到重复内存地址的原因:所有循环迭代中,element.Name 引用的是同一个方法的地址。
✅ 正确写法是显式调用该方法:
for _, element := range systems {
fmt.Println(element.Name()) // 注意括号!
}
? 补充说明与最佳实践:
-
避免使用已弃用的 ioutil:自 Go 1.16 起,ioutil 包已被弃用。建议改用 os.ReadDir(返回 []fs.DirEntry,更轻量)或 os.ReadDir + entry.Info() 获取完整 FileInfo:
entries, err := os.ReadDir("./XML") if err != nil { panic(err) } for _, entry := range entries { fmt.Println(entry.Name()) // fs.DirEntry.Name() 直接返回 string,无需额外调用 Info() } -
错误处理不可省略:原代码忽略 ioutil.ReadDir 的 error 返回值,生产环境应始终检查:
systems, err := ioutil.ReadDir("./XML") if err != nil { log.Fatalf("failed to read directory: %v", err) } 为什么地址相同?
因为 Go 中方法值(method value)在编译期绑定,element.Name 实质是闭包化的 func() string,其底层函数指针对同一类型的所有实例都一致——这不是 bug,而是 Go 方法调用机制的自然表现。
总结:牢记 os.FileInfo.Name 是方法而非字段,调用时务必加 ();升级到 os.ReadDir 可提升性能并简化代码;永远校验 I/O 错误,确保程序健壮性。











