如何处理Firestore DataTo方法中的嵌套指针问题?
问题描述
我定义了以下结构体:
type Address struct { Line1 string `firestore:"line1"` City string `firestore:"city"` } type User struct { Name string `firestore:"name,required"` Email string `firestore:"email,required"` Password string `firestore:"password,required"` Address *Address `firestore:"address"` Age int `firestore:"age,required"` }
向Firestore添加用户文档时一切正常:
docRef, _, err := client.Collection("users").Add(ctx, User{ Name: "John", Email: "jonh.doe@example.com", Password: "123456", Address: &Address{ Line1: "1 Main Road", City: "NY", }, Age: 18, }) if err != nil { fmt.Println(err) } else { fmt.Println(docRef.ID) }
但当我通过查询获取多个用户,并使用DataTo方法转换为User结构体时,所有用户的Address字段似乎指向同一个指针:
var user User var users []User iter := query.Documents(ctx) for { docSnap, err := iter.Next() if err == iterator.Done { break } if err != nil { fmt.Println(err) } err = docSnap.DataTo(&user) if err != nil { fmt.Println(err) } fmt.Println(user) users = append(users, user) } fmt.Println(users)
我是否操作有误?
我知道如果不为Address使用指针就不会有此问题,但由于部分用户可能没有地址(需要nil值),使用指针更合适。这是bug还是预期行为?
问题原因与解决方案
这是预期行为,问题出在你循环复用了同一个user变量。
第一次调用DataTo(&user)时,若user.Address为nil,Firestore客户端库会自动分配新的Address实例并让指针指向它;后续循环中,DataTo会复用已存在的指针指向的实例,直接修改字段值,而非重新分配内存。最终所有添加到users切片的User实例,它们的Address指针都会指向同一内存地址,导致所有用户的Address被最后一次循环的值覆盖。
修复方案
将user变量的声明移到循环内部,每次循环创建新的User实例:
var users []User iter := query.Documents(ctx) for { docSnap, err := iter.Next() if err == iterator.Done { break } if err != nil { fmt.Println(err) continue } var user User // 每次循环生成新实例 err = docSnap.DataTo(&user) if err != nil { fmt.Println(err) continue } fmt.Println(user) users = append(users, user) } fmt.Println(users)
这样每次循环都会创建独立的User和Address实例(若有地址数据),指针指向不同内存空间,就不会出现共享指针的问题了。
内容的提问来源于stack exchange,提问作者CentoKili53
相关产品推荐
相关产品推荐

