2013-05-14 13 views
7

Próbuję zrozumieć, dlaczego następujący kod test nie działa zgodnie z oczekiwaniami:Dlaczego nie wprowadzono zmian w strukturze za pomocą metody?

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" 
} 

Byłoby to wydrukować:

"1" 
"0" 

znaczy, że someStrings widocznie zmodyfikowane ... i to nie jest .

Ktoś wie co może być problemem?

Odpowiedz

12

Metoda addstring stosuje wartość (kopia) odbiornika. Modyfikacja jest wykonywana na kopii, a nie na oryginale. Odbiornik wskaźnik musi być stosowany do mutowania pierwotny podmiot:

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" 
} 

Playground


Wyjście

1 
1 
1

Twoje funkcje są zdefiniowane w obiekcie samych zamiast wskaźnika do obiektu .

func (this Test) AddString(s string) { 
    this.someStrings = append(this.someStrings, s) 
    this.Count() // will print "1" 
} 

Powyższa funkcja jest zdefiniowana na konkretnych danych. Oznacza to, że po wywołaniu funkcji wartość this jest przekazywana jako kopia danych. Tak więc każda mutacja, którą robisz do this, jest wykonywana na kopii (w tym przypadku mutacja zmienia wskaźnik, na który wskazuje `someStrings '. Możemy przepisać tę samą funkcję zdefiniowaną na wskaźniku testu, jak jnml:

func (this *Test) AddString(s string) { 
    this.someStrings = append(this.someStrings, s) 
    this.Count() // will print "1" 
} 

Jak widać, definicja funkcji jest (this *Test) zamiast (this Test). oznacza to, że zmienna this jest przekazywane przez referencję, a wszelkie mutacje, które zachodzą mutacje są wykonywane na oryginalnego obiektu.

Powiązane problemy