L'allocation et l'initialisation des structures Go peuvent être délicates pour les nouveaux arrivants. Prenons cet exemple :
import "sync" type SyncMap struct { lock *sync.RWMutex hm map[string]string } func (m *SyncMap) Put(k, v string) { m.lock.Lock() defer m.lock.Unlock() m.hm[k] = v } func main() { sm := new(SyncMap) sm.Put("Test", "Test") }
Ce code paniquera avec une exception de pointeur nul car lock et hm ne sont pas initialisés.
Pour résoudre ce problème, la solution de contournement suivante peut être utilisée :
func (m *SyncMap) Init() { m.hm = make(map[string]string) m.lock = new(sync.RWMutex) } func main() { sm := new(SyncMap) sm.Init() sm.Put("Test", "Test") }
Mais cela ajoute un passe-partout inutile.
Une approche plus propre est utiliser une fonction constructeur pour initialiser la structure. Un constructeur est une fonction qui renvoie une instance initialisée d'une structure. Par exemple :
func NewSyncMap() *SyncMap { return &SyncMap{hm: make(map[string]string)} }
Ce constructeur initialise le champ hm et renvoie un pointeur vers l'instance SyncMap nouvellement créée.
func main() { sm := NewSyncMap() sm.Put("Test", "Test") }
Maintenant, le code initialise correctement la structure sans aucun passe-partout. .
Le modèle de constructeur peut également être utilisé pour initialiser plusieurs champs, démarrer des goroutines ou enregistrer des finaliseurs pour le structurer. Par exemple :
func NewSyncMap() *SyncMap { sm := SyncMap{ hm: make(map[string]string), foo: "Bar", } runtime.SetFinalizer(sm, (*SyncMap).stop) go sm.backend() return &sm }
Ce constructeur initialise les champs hm et foo, démarre une goroutine pour backend() et enregistre un finaliseur pour exécuter la méthode stop() lorsque l'instance SyncMap est récupérée.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!