2014-12-18 24 views
19

Sono confuso sul modo migliore per inizializzare una struttura che contiene una mappa. L'esecuzione di questo codice produce panic: runtime error: assignment to entry in nil map:golang - come inizializzare un campo mappa all'interno di una struttura?

package main 

type Vertex struct { 
    label string 
} 

type Graph struct { 
    connections map[Vertex][]Vertex 
} 

func main() { 
    v1 := Vertex{"v1"} 
    v2 := Vertex{"v2"} 

    g := new(Graph) 
    g.connections[v1] = append(g.coonections[v1], v2) 
    g.connections[v2] = append(g.connections[v2], v1) 
} 

Un'idea è quella di creare un costruttore, come in this answer.

Un'altra idea è quella di utilizzare un metodo add_connection in grado di inizializzare la mappa se è vuota:

func (g *Graph) add_connection(v1, v2 Vertex) { 
    if g.connections == nil { 
    g.connections = make(map[Vertex][]Vertex) 
    } 
    g.connections[v1] = append(g.connections[v1], v2) 
    g.connections[v2] = append(g.connections[v2], v1) 
} 

Ci sono altre opzioni? Volevo solo vedere se esiste un modo comunemente accettato per farlo.

+2

Un costruttore è il modo comunemente accettato (diverso supponendo che il programmatore può farlo senza assistenza) – JimB

+0

possibile duplicato di [come inizializzare i membri in go struct] (http://stackoverflow.com/questions/4498998/how-to-initialize-members-in-go-struct) – JimB

risposta

28

avrei probabilmente usare un costruttore per fare questo:

func NewGraph() *Graph { 
    var g Graph 
    g.connections = make(map[Vertex][]Vertex) 
    return &g 
} 

ho trovato questo esempio nel image/jpeg pacchetto standard (non con una mappa però , ma con una sezione):

type Alpha struct { 
    Pix []uint8 
    Stride int 
    Rect Rectangle 
} 

func NewAlpha(r Rectangle) *Alpha { 
    w, h := r.Dx(), r.Dy() 
    pix := make([]uint8, 1*w*h) 
    return &Alpha{pix, 1 * w, r} 
} 
+1

fantastico, grazie per aver trovato l'esempio nella lib standard, che ispira decisamente fiducia – Matt

13

È molto comune che il codice (in particolare il codice completamente sotto il vostro controllo) presupponga di inizializzare correttamente la struttura dati. Un letterale struct è di solito usato in questo caso

g := &Graph{ 
    connections: make(map[Vertex][]Vertex), 
} 
+0

Ma come si inizializza il valore delle connessioni con alcuni particolari valore? –

1

I letterali compositi funzionano bene all'interno di un costruttore. Escogitando un esempio utilizzando la domanda iniziale (e ingenuamente memorizzando copie di vertici nella mappa):

func NewGraph(v1 Vertex, v2 Vertex) *Graph { 
    return &Graph{ map[Vertex][]Vertex{ v1: []Vertex{v2}, v2: []Vertex{v1} }} 
} 

func main() { 
    v1 := Vertex{"v1"} 
    v2 := Vertex{"v2"} 

    g := NewGraph(v1, v2) 
    fmt.Println(g) 
} 

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

Problemi correlati