Почему изменения, внесенные в структуру с помощью метода, не сохраняются?

Я пытаюсь понять, почему следующий тестовый код не работает, как ожидалось:

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 передается по ссылке, и любые мутации, которые происходят мутации, проведенные на исходный объект.