Cette question trahit mon manque fondamental de compréhension des pointeurs Golang (ou de n'importe quel pointeur, vraiment), alors s'il vous plaît ours avec moi. J'ai aussi mis un exemple similaire, travaillant sur Go Playground s'il est utile:Réinitialisation des pointeurs dans les boucles
https://play.golang.org/p/Xe-ZRdFWGp
Supposons que j'ai une relation parent/enfant de base avec deux struct:
//Parent
type User struct{
ID int
Rsvps []*Rsvp
}
//Child
type Rsvp struct{
Response string
}
À un moment donné , un groupe d'utilisateurs et RSVPs est créé, et les informations stockées dans une base de données. À un moment donné, il sera temps d'extraire des informations de cette base de données et de les réécrire dans ces structures. Lorsque j'utilise une base de données relationnelle, j'essaye généralement de le faire avec une seule requête, dans un modèle que j'utilise depuis de nombreuses années, mais qui n'est peut-être plus le bon. Je vais mettre en place une boucle pour extraire les données. Voici quelques pseudocode avec de nombreux commentaires:
func getUsersAndRsvps() []*User{
sql := "SELECT * FROM users LEFT JOIN rsvps ON users.field1 = rsvps.field1 ORDER BY user.ID;"
dataset := getDataset(sql)
result = []*User{}
rsvps = []*Rsvp{}
//Oh, but you already see the problem here, don't you! I'm defining
//rsvps outside of the loop, and the values contained at its address
//will become values for all users, instead of per user. Yet, how
//else can I collect together rsvps while iterating?
user = User{} //hold onto a user while iterating
lastUserID := int64(0) //track when we move from one user to the next
for _, record := range dataset{
thisUserID := record.ID
//When this user is different from last user
//take the collected rsvps and write them into
//the (old) user, then continue iterating...
if lastUserID != thisUserID && lastUserID > 0{
//So, right here is the big problem. I'm writing
//the address of collected rsvps into the previous user record.
//However, on each iteration, that address gets all
//new info, such that at the end of the readout,
//all users have the same rsvps.
user.Rsvps = rsvps
result = append(result, &user)
//So, yes, I "blank out" the rsvps, but that only goes
//to make the last user's rsvps be those shared among all
rsvps = []*Rsvp{}
}
//Gather rsvps
rsvp = getRsvp(rsvp) //defined elsewhere
rsvps = append(rsvps, &rsvp)
user = getUser(record) //defined elsewhere
lastUserID := thisUserID
}
//Capture last record
user.Rsvps = rsvps
result = append(result, &user)
}
Pour rendre la question succincte et nous espérons clairement, comment puis-je itérer à travers un ensemble de données, la collecte des éléments dans une tranche, puis écrire cette tranche en un point unique de mémoire telle que la le prochain jeu d'itérations ne l'écrasera pas?
Chaque variable est écrite dans sa propre mémoire. Si vous voulez qu'une variable persiste en dehors de la portée d'une boucle (ou de n'importe quel bloc), déclarez la variable en dehors de ce bloc. – Adrian
Oui. Je pense que c'est ce que je fais, à moins que je ne comprenne mal votre solution. J'ai placé la variable de pointeur de pointeur en dehors de la portée de boucle, seulement pour la voir réécrire à chaque itération. – Brent
Quelle variable est écrasée? – Adrian