2015-06-11 5 views
7

Sono confuso dai metodi golang sulle strutture. Ho seguito lungo in un tutorial in cui sono:I puntatori sono stati deferiti per impostazione predefinita nei metodi della struttura golang?

func (p *Page) save() error { 
    filename := p.Title + ".txt" 
    return ioutil.WriteFile(filename, p.Body, 0600) 
} 

Dalla mia comprensione p è puntatore e si avrebbe bisogno di dereference il puntatore prima di recuperare una proprietà, ad esempio:

filename := (*p).Title + ".txt" 

L'unica il modo in cui questo ha senso per me è se il punto agisce come -> in C++. Cosa mi manca?

+0

Non sono sicuro del motivo per cui sei stato downvoted, accetta il mio upvote. – getWeberForStackExchange

risposta

15

Sì, il puntatore alla struct è dereferenziato automaticamente. Dalla spec on selectors:

valgono le seguenti regole di selettori:

  1. Per un valore x di tipo T o *T dove T non è un puntatore o interfaccia tipo, x.f indicato il campo o il metodo a profondità più bassa in T dove c'è un tale f. Se non c'è esattamente uno f con profondità minima di , l'espressione del selettore è illegale.

...

  1. In via eccezionale, se il tipo di x è un tipo di puntatore di nome e (*x).f è un'espressione di selezione valida che denota un campo (ma non una Metodo ), x.f è abbreviazione di (*x).f.

Pertanto, le due istruzioni seguenti sono gli stessi (con il primo è preferito):

filename := p.Title + ".txt" 
filename := (*p).Title + ".txt" 
+0

Ok, buono a sapersi! Accetterò quando posso. – m0meni

1

Non c'è bisogno di deferenza puntatori o utilizzare un operatore di accesso speciale per accedere ai campi di una struttura in Go.

myRef := &ILikeCompositeLiteralInitilization{} 
fmt.Println(myRef.Dereferenced); 

è funzionalmente equivalente a;

fmt.Printn((*myRef).Dereferenced); 

Possibilmente pena notare che il comportamento di funzioni non è così. Significa, dovrei dereferenziare per invocare un metodo che riceve il tipo è il valore e non un puntatore. IE;

func (*ILikeCompositeLiteralInitilization) PointerVersion() 
func (ILikeCompositeLiteralInitilization) ValueVersion() 

myRef.PointerVersion() // compiler likes this 

myRef.ValueVersion() // won't compile 

(*myRef).ValueVersion() // compiler is OK with this 

In sostanza, con funzioni non dereferenziare implicita o l'indirizzo del tipo di operazione si verificherà, il codice non compilazione.

Problemi correlati