2016-07-06 73 views
5

Ho la seguente coppia definita nel mio programma di andarenon può assegnare accoppiare in una mappa

type pair struct { 
    a float64 
    b float64 
} 

Poi ho creare una mappa:

dictionary map[string]pair 

ho aggiungo un elemento:

dictionary["xxoo"] = pair{5.0, 2.0} 

Quindi sto cercando di fare questo:

dictionary["xxoo"].b = 5.0 // try to change from 2.0 to 5.0 

L'ultima riga non compila e ha detto che "non può assegnare ad essa"

Voglio sapere qual è la ragione di questo?

+1

curiosità: si fa anche si aspetta un linguaggio di programmazione ad avere un tipo predefinito per una tripla - una tupla di tre elementi? Quattro? 'N'? Cosa c'è di speciale in * una coppia? * – kostix

+1

https://github.com/golang/go/issues/3117 – gavv

risposta

3

Questo non è legale per motivi descritti here:

Interrogazione di una mappa dare una copia della voce memorizzata, quindi non c'è nessun punto assegnando ad esso.

La soluzione consigliata è:

var xxoo = dictionary["xxoo"] 
xxoo.b = 5.0 
dictionary["xxoo"] = xxoo 
2

E 'vietato come detto in risposta Thomas'. Utilizzare invece i puntatori.

dict := map[string]*pair{} 
dict["xxoo"] = &pair{5.0, 2.0} 
fmt.Println(dict["xxoo"].b) // 2 
dict["xxoo"].b = 5.0 
fmt.Println(dict["xxoo"].b) // 5 

https://play.golang.org/p/nEr_WrQOly

6

Per assegnare un valore a un campo struct, che struct deve essere "indirizzabile". L'indirizzabilità è trattata nella sezione "Address Operators" delle specifiche della lingua.

I valori delle mappe non sono indirizzabili per lasciare alle implementazioni della mappa la libertà di spostare i valori nella memoria, se necessario. Poiché i valori della mappa non sono indirizzabili, non è possibile utilizzare un selettore (.) sul valore da assegnare al campo struct. Se si utilizza un tipo di puntatore come valore della mappa, ad esempio map[string]*pair, il puntatore indiretto soddisfa il requisito di indirizzabilità.

dict := make(map[string]*pair) 
dict["xxoo"] = &pair{5.0, 2.0} 
dict["xxoo"].b = 5.0 

Se si lavora con i valori, è necessario copiare il valore esistente tramite l'assegnazione, o fornire un valore del tutto nuova:

dict := make(map[string]pair) 
dict["xxoo"] = pair{5.0, 2.0} 

// copy the value, change one field, then reassign 
p := dict["xxoo"] 
p.b = 5.0 
dict["xxoo"] = p 

// or replace the value in full 
dict["xxoo"] = pair{5.0, 5.0} 
+0

Forse questa risposta è un po 'meglio: i valori memorizzati in una mappa non sono indirizzabili perché le implementazioni della mappa sono liberi di spostare i valori che memorizzano in modo arbitrario. Questo è necessario per molti approcci per implementare le mappe in modo efficace. Se i valori si spostano nella memoria, non è possibile restituire un puntatore a tale valore. – kostix

+0

@kostix: stavo cercando di evitare i dettagli dell'implementazione della mappa, che sono un altro toppic, ma immagino che non faccia male menzionarlo. – JimB