この質問はGolangポインタ(または実際にはポインタ)の私の基本的な欠如を裏切っています。私それは便利です場合も行く遊び場に類似し、作業例を入れている:いくつかの時点でループ内のポインタをリセットする
//Parent
type User struct{
ID int
Rsvps []*Rsvp
}
//Child
type Rsvp struct{
Response string
}
:
https://play.golang.org/p/Xe-ZRdFWGp
を私は2つの構造体の基本的な親/子関係を持っていると仮定多数のユーザとRSVPが作成され、情報がデータベースに格納されます。ある時点で、そのデータベースから情報を抽出し、これらの構造体に書き戻す時間が来るでしょう。リレーショナルデータベースを使用する場合、私は長年使用してきたパターンで、通常は単一のクエリでそれを実行しようとしますが、もう正しい方法ではない可能性があります。私はデータを抽出するためのループを設定します。ここでは多くのコメントといくつかの擬似コードです:
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)
}
質問は簡潔でうまくいけば明確にするために、どのように私はスライスにアイテムを収集し、データセットを反復処理します、そして、次に、そのユニークなメモリポイントにそのスライスを書きます次の反復のセットはそれを上書きしませんか?
すべての変数は、それぞれのメモリに書き込まれます。ループのスコープ(または任意のブロック)の外に変数を残したい場合は、変数をそのブロックの外に宣言します。 – Adrian
はい。私はあなたのソリューションを誤解していない限り、私がやっていることだと思います。ポインタのスライス変数をループスコープの外に設定し、各繰り返しで書き換えられるのを見るだけです。 – Brent
どの変数が上書きされていますか? – Adrian