2012-08-04 11 views
42

Dopo aver creato una struttura come questa:come impostare e ottenere campi nelle strutture Golang?

type Foo struct { 
    name string   

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

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

Come si crea una nuova istanza di Foo e impostare e ottenere il nome? Ho provato quanto segue:

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

Nulla viene stampato, perché il nome è vuoto. Quindi, come faccio a impostare e ottenere un campo all'interno di una struttura?

risposta

89

Commentary (e di lavoro) Esempio:

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 e prendere A Tour of Go per imparare di più su metodi e indicatori, e le basi di Go a tutti.

+14

Nome() sarebbe il nome idiomatico per il getter (vedere http://golang.org/doc/effective_go.html#Getters) –

+1

Questa dovrebbe essere la risposta accettata! –

+0

@Anonimo Hai ragione, ho modificato la risposta. –

4

Per esempio,

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

uscita:

Abc 
+1

Mentre tecnicamente la tua risposta funzionerà, GetFoo() non è il getter idiomatico che dà il nome a Foo in Go: dovrebbe essere solo Foo(). Maggiori dettagli nella risposta di Zippoxer. – FGM

+1

è un buon esempio, ma per il metodo 'GetName()' non è necessario passarlo con un puntatore 'func (f * Foo)' si dovrebbe andare bene con 'func (f Foo)' perché non si ' t modificare il valore appena letto/restituirlo. –

+0

@Hoenir: "Scegliere se utilizzare un valore o un ricevitore puntatore su metodi può essere difficile, specialmente per i nuovi programmatori Go. In caso di dubbio, utilizzare un puntatore." [Tipo di ricevitore, Commenti di revisione del codice Go] (https://github.com/golang/go/wiki/CodeReviewComments#receiver-type). Questo è un esempio forzato, non sappiamo quanto sarà grande la struttura attuale. Pertanto, usiamo un puntatore. – peterSO

22

Setter e getter non sono che idiomatica to Go. Soprattutto il getter per un campo x non è nominato GetX ma solo X. Vedere http://golang.org/doc/effective_go.html#Getters

Se il setter non fornisce la logica speciale, per esempio logica di convalida, non c'è niente di sbagliato con l'esportazione il campo e non fornendo un setter, né un metodo getter . (Questo sembra sbagliato per qualcuno con uno sfondo Java . Ma non lo è.)

+11

Parte del motivo per nascondere l'informazione (incapsulamento) è l'evoluzione del programma. Semplicemente non dividi il tuo codice ovunque con accesso diretto. Diciamo che dopo 1 anno, decidi di implementare la validazione o qualcosa anche un po 'diverso. Non vuoi refactoring in mille luoghi diversi ma solo un singolo file e un singolo posto. Lanciare le pratiche e il pensiero stabiliti da altre lingue non è SEMPRE la cosa giusta da fare. – sat

+1

@sat Se devi refactoring di un migliaio di posti, forse stai facendo qualcosa di sbagliato in primo luogo. – Profpatsch

+4

@sat (e tutti gli upvoters): Il refactoring di diverse migliaia di siti di chiamate in Go non è così complicato. Gofix esiste ancora e altri strumenti stanno maturando velocemente. Ultimo non ultimo: Wrapping di tutti gli accessi solo perché potresti voler modificare questo accesso viola YAGNI e aiuta solo se il refactoring ** può ** essere eseguito cambiando il getter da solo (nessun errore aggiuntivo, nessun altro refactoring). Ho sentito questo tipo di argomenti troppo spesso. Se l'API è ben progettata, non affronterai questi problemi e se l'API è pessima hai perso comunque. – Volker

Problemi correlati