Почему изменения, внесенные в структуру с помощью метода, не сохраняются?
Я пытаюсь понять, почему следующий тестовый код не работает, как ожидалось:
package main
import (
"fmt"
"strings"
)
type Test struct {
someStrings []string
}
func (this Test) AddString(s string) {
this.someStrings = append(this.someStrings, s)
this.Count() // will print "1"
}
func (this Test) Count() {
fmt.Println(len(this.someStrings))
}
func main() {
var test Test
test.AddString("testing")
test.Count() // will print "0"
}
Это печатать:
"1"
"0"
означает, что someStrings
это, видимо, изменен... а потом-нет.
кто-нибудь знает, в чем может быть проблема?
2 ответов
метод AddString использует приемник value (copy). Изменения вносятся в копию, а не в оригинал. Приемник указателя должен использоваться для изменения исходного объекта:
package main
import (
"fmt"
)
type Test struct {
someStrings []string
}
func (t *Test) AddString(s string) {
t.someStrings = append(t.someStrings, s)
t.Count() // will print "1"
}
func (t Test) Count() {
fmt.Println(len(t.someStrings))
}
func main() {
var test Test
test.AddString("testing")
test.Count() // will print "0"
}
выход
1
1
ваши функции определяются на самом объекте, а не указателем на объект.
func (this Test) AddString(s string) {
this.someStrings = append(this.someStrings, s)
this.Count() // will print "1"
}
функция выше определена на конкретных данных. Это означает, что при вызове функции, значение this
передается как копия данных. Так что любые мутации вы делаете, чтобы this
выполняются на копии (в этом случае мутация изменяет указатель, на который указывает' someStrings'. Мы можем переписать ту же функцию, определенную на указателе Test как jnml сделал:
func (this *Test) AddString(s string) {
this.someStrings = append(this.someStrings, s)
this.Count() // will print "1"
}
как вы можете видеть, определение функции (this *Test)
вместо (this Test)
. Это означает, что переменная this
передается по ссылке, и любые мутации, которые происходят мутации, проведенные на исходный объект.