2016-07-06 11 views
5

Mam następujące pary określonego w mój programnie można przypisać do parowania w mapie

type pair struct { 
    a float64 
    b float64 
} 

Potem stworzyć mapę:

dictionary map[string]pair 

ja najpierw dodać jeden element:

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

Następnie próbuję to zrobić:

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

Ostatnia linia nie kompiluje i powiedział „nie można przypisać do niego”

Chcę wiedzieć, co jest tego powodem?

+1

Z ciekawości: czy też spodziewać się języka programowania, aby mieć predefiniowany typ dla potrójnej - krotka trzech elementów? Cztery? 'N'? Co jest takiego specjalnego w * parze? * – kostix

+1

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

Odpowiedz

3

To nie jest prawną powodów opisanych here:

Zapytania mapa dać kopię zapisanych pozycji, więc nie ma sensu przypisywanie do niego.

Zalecana obejście jest:

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

Zabronione jak powiedział w odpowiedzi Thomasa. Zamiast tego użyj wskaźników.

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

Aby przypisać wartość do pola struct, że struktura musi być "adresowalny". Adresowanie jest opisane w sekcji "Address Operators" specyfikacji językowej.

Wartości map nie są adresowalne, aby pozostawić implementacje map jako swobodę przenoszenia wartości w pamięci w razie potrzeby. Ponieważ wartości map nie można adresować, nie można użyć operatora selektora (.) na wartości do przypisania do pola struct. Jeśli używasz typu wskaźnika jako wartości mapy, tj. map[string]*pair, wskaźnik w kierunku indeksu spełnia wymagania dotyczące adresacji.

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

Jeśli pracujesz z wartościami, trzeba skopiować istniejącą wartość poprzez przypisanie lub dostarczamy zupełnie nową wartość:

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

Aby możliwe było zrobienie tej odpowiedzi nieco lepiej: wartości zapisane na mapie nie są adresowalne, ponieważ implementacje map są swobodnie przenosić wartości, które przechowują w pamięci w dowolny sposób. Jest to wymagane w przypadku wielu podejść do skutecznego wdrażania map. Jeśli wartości mogą poruszać się w pamięci, nie można zwrócić wskaźnika do takiej wartości. – kostix

+0

@kostix: Próbowałem uniknąć szczegółów implementacji mapy, które są kolejną toppiką, ale myślę, że nie zaszkodzi wspomnieć o tym. – JimB

Powiązane problemy