Je suis confus quant à la meilleure façon d'initialiser une structure qui contient une carte. L'exécution de ce code produit panic: runtime error: assignment to entry in nil map
:
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)
}
Une idée est de créer un constructeur, comme dans cette réponse .
Une autre idée est d'utiliser un add_connection
méthode qui peut initialiser la carte si elle est vide:
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)
}
Y a-t-il d'autres options? Je voulais juste voir s'il y avait une façon communément acceptée de le faire.
J'utiliserais probablement un constructeur pour faire ceci:
func NewGraph() *Graph {
var g Graph
g.connections = make(map[Vertex][]Vertex)
return &g
}
J'ai trouvé cet exemple dans la norme image/jpeg
package (pas avec une carte, mais avec une tranche):
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}
}
Il est très courant que le code (en particulier le code entièrement sous votre contrôle) suppose que vous initialisez correctement la structure de données. Un littéral struct est généralement utilisé dans ce cas
g := &Graph{
connections: make(map[Vertex][]Vertex),
}
Les littéraux composites fonctionnent très bien à l'intérieur d'un constructeur. Création d'un exemple à l'aide de la question initiale (et stockage naïf de copies de sommets dans la carte):
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)
}