重置循环中的指针

This question betrays my basic lack of understanding of Golang pointers (or any pointer, really), so please bear with me. I've also put a similar, working example on Go Playground if it's helpful:

https://play.golang.org/p/Xe-ZRdFWGp

Suppose that I have a basic parent/child relationship with two structs:

//Parent
type User struct{
     ID int
     Rsvps []*Rsvp
}   

//Child
type Rsvp struct{
   Response string
}

At some point, a bunch of users and RSVPs is created, and the information stored in a database. At some point, it will come time to extract information from that database and write it back into these structs. When using a relational database, I'll typically try to do it with a single query, in a pattern I've been using for many years, but which may not be the right way any more. I'll to set up a loop to extract the data. Here's some pseudocode with many comments:

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)

}

To make the question succinct and hopefully clear, how do I iterate through a dataset, collecting items into a slice, and then write that slice into a unique memory point such that the next set of iterations won't overwrite it?

The problem is not caused by a pointer to Rsvp but the following statement(s):

user := User{} //hold onto a user while iterating

//... omitted for clarity
for _, record := range dataset{
    //...   
    if lastUserID != thisUserID && lastUserID > 0{
        //... 

        /*--- The problem is here ---*/
        result = append(result, &user)

        //...
    }
    //...       
    user = getUser(record) //defined elsewhere
    //...
}

During each iteration, the value of variable user is overwritten, but since variable user is defined outside the loop, address to variable user (i.e. &user) will remain the same. As a result, the elements in result slice will be the same, i.e. address to single user variable, in which its value is captured from last record. Change the append statement to:

//result = append(result, &user)
u := user
result = append(result, &u)

A minimum example to demonstrate the issue can be found at The Go Playground.

How about you do the following:

    package main

    import (
        "fmt"
    )

    type User struct {
        ID    int
        Rsvps []*Rsvp
    }

    type Rsvp struct {
        Response string
    }

    func main() {
        users := []int{1, 2, 3}
        responses := []string{"Yes", "No", "Maybe"}
        var results []*User
        for _, i := range users {
            r := Rsvp{Response: responses[i-1]} // create new variable
            u := User{ID: i}
            u.Rsvps = append(u.Rsvps, &r)
            results = append(results, &u)
        }
        for _, r := range results {
            fmt.Println(r.ID, r.Rsvps[0].Response)
        }

    }

I have taken your playground example, stripped the comments and changed the code to get your desired output. The main change is that I do not re-use r. Originally you were always appending &r but changing r at the start of the loop. Of course this changes the memory that r points to, making everything a Maybe.