Remove an element of a slice in a struct [duplicate]

北城余情 提交于 2019-12-02 10:03:58

Any method that intends / does modify the receiver must use a pointer receiver.

Your Guest.removeFriend() method indeed tries to modify the receiver (of type Guest), namely its friends field (which is of slice type), but since you only used a value receiver, you are only modifying the friends field of a Guest copy. The original Guest value will have the unmodified slice value.

So you must use a pointer receiver:

func (self *Guest) removeFriend(id int) {
    // ...
}

Testing it:

g := &Guest{
    id:      1,
    name:    "Bob",
    surname: "Pats",
    friends: []int{1, 2, 3, 4, 5},
}

fmt.Println(g)
g.removeFriend(3)
fmt.Println(g)

Output (try it on the Go Playground):

&{1 Bob Pats [1 2 3 4 5]}
&{1 Bob Pats [1 2 4 5]}

The explanation for what you see in your version that slices are small struct descriptors pointing to an array that actually holds the elements. In your example you modified the elements of the backing array, so the caller having the original slice will see those modifications, but the size of the original slice will not (cannot) change.

By using a pointer receiver, you will assign the new slice value (returned by append()) to the friends field of the original Guest, the slice value whose length will be smaller by 1 (due to the 1 removed element).

Also note that in Go using receiver names like self and this is not idiomatic, instead you could use guest or simply g.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!