Go 中返回的是指针,但你却能直接用"."访问字段,看起来像是"没有解引用",其实是 Go 帮你自动处理了"指针解引用"的语法糖。
在 Go 中,如果你有一个结构体指针(例如 *FileMeta),你可以直接用 p.Field 的方式访问字段,Go 会自动帮你做 (*p).Field 的转换。
🧠 背后原理:自动解引用(auto dereferencing)
go
type FileMeta struct {
FileName string
}
var f = &FileMeta{FileName: "test"}
fmt.Println(f.FileName) // ✅ 等价于 fmt.Println((*f).FileName)
Go 编译器会自动将指针字段访问 f.Field 翻译为 (*f).Field,这叫做"自动解引用",是 Go 语言为了简化语法做的语法糖处理。
❓ 那什么时候需要 * 解引用?
你只在需要整个值而不是字段的时候才需要手动解引用,例如赋值、拷贝等:
go
p := &Person{Name: "Alice"}
val := *p // 拷贝整个结构体
fmt.Println(val.Name)
今天在写代码的时候发现的很奇妙的go特性:go不需要手动解引用,可以直接.field取值
go
func GetFileInfo(fileSha1 string) (*fileInfo, bool) {
stmt, err := mydb.DBconn().Prepare(
"select file_sha1,file_addr,file_name,file_size from tbl_file " +
"where file_sha1=? and status=1 limit 1")
if err != nil {
fmt.Println(err)
return &fileInfo{}, false
}
defer stmt.Close()
fileInfo := fileInfo{}
//var fileInfo fileInfo
err = stmt.QueryRow(fileSha1).Scan(&fileInfo.FileSha1, &fileInfo.Location, &fileInfo.FileName, &fileInfo.FileSize)
if err != nil {
fmt.Println("查询失败!" + err.Error())
return &fileInfo, false
}
return &fileInfo, true
}
go
func GetFileMetaDB(filehash string) (*FileMeta, bool) {
fileInfo, ok := db.GetFileInfo(filehash)
if !ok {
return &FileMeta{}, false
}
filemetaDB := FileMeta{
FileSha1: fileInfo.FileSha1,
FileSize: fileInfo.FileSize.Int64,
Location: fileInfo.Location.String,
FileName: fileInfo.FileName.String,
}
return &filemetaDB, true
}