2016-04-02 21 views
7

Ecco un breve esempio per dimostrare:Perché non si può assegnare agli array all'interno delle mappe in Go?

package main 

import "fmt" 

func main() { 
    array := [3]int{1, 2, 3} 
    array[0]++ // Works 
    slice := make([]int, 3) 
    for i := range slice { 
     slice[i] = i + 1 
    } 
    arrayMap := make(map[int][3]int) 
    sliceMap := make(map[int][]int) 
    arrayMap[0] = array 
    sliceMap[0] = slice 
    //arrayMap[0][0]++ // Does not compile: "cannot assign to arrayMap[0][0]" 
    sliceMap[0][0]++ 
    fmt.Println(arrayMap) 
    fmt.Println(sliceMap) 
} 

Perchè non posso modificare il contenuto di un array se è all'interno di una mappa, anche se sono mutabili di fuori della mappa? E perché funziona con le fette?

+2

Possibile duplicato di [Come modificare la mappa in go] (http://stackoverflow.com/questions/31633453/how-to-modify-map-in-go) –

risposta

5

Per le mappe, i relativi valori non sono indirizzabili. Cioè, quando si utilizza un value type (gli array sono value types in Go), non è possibile indirizzare il valore utilizzando ++.

Tuttavia, se si utilizza un reference type (le sezioni sono reference types in Vai), è possibile farlo come già accennato nell'esempio.

Ciò vale a prescindere dal tipo utilizzato nella mappa.

Una cosa che possiamo fare è utilizzare l'indirizzo ptr del tipo. Ad esempio, se si prende l'indirizzo della matrice, quindi dovrebbe funzionare:

Playground: http://play.golang.org/p/XeIThVewWD

package main 

import "fmt" 

func main() { 
    array := [3]int{1, 2, 3} 
    slice := []int{1, 2, 3} 

    arrayMap := make(map[int]*[3]int) // use the pointer to the type 
    sliceMap := make(map[int][]int) 
    arrayMap[0] = &array // get the pointer to the type 
    sliceMap[0] = slice 

    arrayMap[0][0]++ // works, because it's a pointer to the array 
    sliceMap[0][0]++ 

    fmt.Println(*arrayMap[0]) 
    fmt.Println(sliceMap[0]) 
} 

// outputs 
[2 2 3] 
[2 2 3] 

questo funziona e incrementa l'indice di [0]array-2, come previsto.

Funziona perché Go gracious dereferences puntatori per noi al suo valore durante la lettura e aggiorna il valore durante la riassegnazione.

+1

[Lo stesso è vero quando è un campo struct piuttosto di un valore in un array.] (http://play.golang.org/p/R3IFmhHk7Z) In entrambi i casi, è necessario utilizzare un puntatore o copiare il valore dalla mappa in una var, apportare la modifica e assegnare torna indietro (probabilmente non così lento come può sembrare). – twotwotwo