猿问

如何修改嵌套结构的属性值

我正在尝试修改 Go 中嵌套结构变量的值。基本上,我想修改RsvpString属性,但GetRsvp()似乎返回值Rsvp而不是引用,因此当我修改其属性值时,它不会反映在实例中Event。


测试如下。


type Event struct {

    Rsvps     []Rsvp `json:"rsvps"`

}


type Rsvp struct {

    UserId          string `json:"userId"`

    RsvpString      string `json:"rsvp"`

}


func (e *Event) GetRsvp(userId string) (rsvp *Rsvp, err error) {

    for _, element := range e.Rsvps {

        if element.UserId == userId {

            return &element, nil

        }

    }

    return &Rsvp{}, fmt.Errorf("could not find RSVP based on UserID")

}


func (e *Event) UpdateExistingRsvp(userId string, rsvpString string) {

    rsvp, err := e.GetRsvp(userId)

    if err == nil {

        rsvp.RsvpString = rsvpString

    }

}


这是测试代码:


func TestEvent_UpdateExistingRsvp(t *testing.T) {

    e := Event{[]Rsvp{

        {Name:      "Bill",

            UserId:    "bill",

            Rsvp:      "yes"}}}


    e.UpdateExistingRsvp("bill", "no")

    assert.Equal(t, "no", e.Rsvps[0].Rsvp, "RSVP should be switched to no") // fails

}


慕娘9325324
浏览 105回答 2
2回答

倚天杖

GetRsvp返回循环变量的地址,而不是数组中元素的地址。修理:    for i, element := range e.Rsvps {        if element.UserId == userId {            return &e.Rsvps[i], nil        }    }循环变量保留 e.Rsvps[i] 的副本,并且它在每次迭代时都会被覆盖。如果返回循环变量的地址,则返回该副本的地址。

Helenr

当范围覆盖切片时,每次迭代都会返回两个值。第一个是索引,第二个是该索引处元素的副本。因此从技术上讲,您正在尝试修改 Rsvp 的副本。相反,从 GetRsvp() 方法返回索引并更新。func (e *Event) GetRsvp(userId string) (int, error) {    for index , element := range e.Rsvps {        if element.UserId == userId {            return index, nil        }    }    return -1 , fmt.Errorf("could not find RSVP based on UserID")}func (e *Event) UpdateExistingRsvp(userId string, rsvpString string) {    index, err := e.GetRsvp(userId)    if err != nil || index == -1  {        fmt.Println("no such user")    }    e.Rsvps[index].RsvpString = rsvpString}
随时随地看视频慕课网APP

相关分类

Go
我要回答