2012-08-04 6 views
42

Po utworzeniu struct tak:jak ustawić i uzyskać pola w strukturach Golanga?

type Foo struct { 
    name string   

} 
func (f Foo) SetName(name string){ 
    f.name=name 
} 

func (f Foo) GetName string(){ 
    return f.name 
} 

Jak utworzyć nową instancję Foo i ustawiać i uzyskać nazwę? Próbowałem następujące:

p:=new(Foo) 
p.SetName("Abc") 
name:=p.GetName() 
fmt.Println(name) 

Nic nie zostanie wydrukowany, ponieważ nazwa jest pusta. Jak ustawić i uzyskać pole wewnątrz struktury?

Odpowiedz

89

Komentarz (i pracy) przykład:

package main 

import "fmt" 

type Foo struct { 
    name string 
} 

// SetName receives a pointer to Foo so it can modify it. 
func (f *Foo) SetName(name string) { 
    f.name = name 
} 

// Name receives a copy of Foo since it doesn't need to modify it. 
func (f Foo) Name() string { 
    return f.name 
} 

func main() { 
    // Notice the Foo{}. The new(Foo) was just a syntactic sugar for &Foo{} 
    // and we don't need a pointer to the Foo, so I replaced it. 
    // Not relevant to the problem, though. 
    p := Foo{} 
    p.SetName("Abc") 
    name := p.Name() 
    fmt.Println(name) 
} 

Test it i wziąć A Tour of Go aby dowiedzieć się więcej na temat metod i wskaźników, a podstawami idź na wszystkich.

+14

Nazwa() byłaby idiomatyczną nazwą gettera (patrz http://golang.org/doc/effective_go.html#Getters) –

+1

To powinna być zaakceptowana odpowiedź! –

+0

@ Anonim Masz rację, zredagowałem odpowiedź. –

4

Na przykład

package main 

import "fmt" 

type Foo struct { 
    name string 
} 

func (f *Foo) SetName(name string) { 
    f.name = name 
} 

func (f *Foo) Name() string { 
    return f.name 
} 

func main() { 
    p := new(Foo) 
    p.SetName("Abc") 
    name := p.Name() 
    fmt.Println(name) 
} 

wyjściowa:

Abc 
+1

Podczas gdy technicznie twoja odpowiedź zadziała, GetFoo() nie jest idiomatycznym nazwiskiem gettera dla Foo in Go: powinno to być po prostu Foo(). Więcej szczegółów w odpowiedzi Zippoxera. – FGM

+1

to dobry przykład, ale dla metody 'GetName()' nie musisz przekazywać jej przez wskaźnik 'func (f * Foo)' powinieneś być w porządku z 'func (f Foo)', ponieważ nie masz t zmienić wartość, którą właśnie przeczytałeś/zwróciłeś. –

+0

@Henen: "Wybór, czy używać metody wartości lub wskaźnika dla metod, może być trudny, szczególnie dla nowych programistów Go.Jeśli masz wątpliwości, użyj wskaźnika." [Typ odbiornika, komentarze do przeglądania kodu dostępu] (https://github.com/golang/go/wiki/CodeReviewComments#receiver-type). To jest wymyślny przykład, nie wiemy, jak duża będzie faktyczna struktura. Dlatego używamy wskaźnika. – peterSO

22

setery i pozyskiwaniu nie że idiomatyczne iść. Zwłaszcza getter dla pola X nie jest nazwany GetX ale po prostu X. Zobacz http://golang.org/doc/effective_go.html#Getters

Jeśli setter nie przewiduje specjalnej logiki, np logika walidacji, nie ma nic złego w wyeksportowaniu pola i ani nie dostarczając metody ustawiającej ani pobierającej . (To po prostu źle dla kogoś, kto ma tło Java w wersji , ale tak nie jest.)

+11

Jednym z powodów ukrywania informacji (enkapsulacji) jest ewolucja programu. Po prostu nie rozpylasz swojego kodu wszędzie z bezpośrednim dostępem. Powiedzmy, że po roku, decydujesz się na wdrożenie walidacji lub coś jeszcze innego. Nie chcesz zreorganizować tysiąca różnych miejsc, ale tylko jeden plik i jedno miejsce. Wyrzucanie ustalonych praktyk i myśli z innych języków nie jest ZAWSZE słuszne. – sat

+1

@sat Jeśli musisz refaktoryzować tysiące miejsc, być może robisz coś złego w pierwszej kolejności. – Profpatsch

+4

@sat (i wszystkie windy): Refaktoryzacja kilku tysięcy stron wywołań w Go nie jest aż tak skomplikowana. Gofix nadal istnieje, a inne narzędzia szybko dojrzewają. Last not least: Zawijanie całego dostępu tylko dlatego, że możesz chcieć zmienić ten dostęp, narusza YAGNI i pomaga tylko wtedy, gdy refaktoryzacja ** może ** zostać wykonana poprzez zmianę samego gettera (bez dodatkowego przypadku błędu, bez innych refaktoryzacji). Tego typu argumenty słyszałem zbyt często. Jeśli interfejs API jest dobrze zaprojektowany, nie będziesz musiał stawić czoła tym problemom, a jeśli API jest zły, to i tak przegrywasz. – Volker

Powiązane problemy