Comment initialiser les membres dans go struct

je suis nouveau à Golang afin de répartition en ce qui me rend fou:

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, true
}

et plus tard, je viens d'appeler:

sm := new(SyncMap)
sm.Put("Test, "Test")

en ce moment j'ai un signal de panique nul.

j'ai travaillé autour de lui en utilisant une autre fonction, et l'appelant juste après new() :

func (m *SyncMap) Init() {
        m.hm = make(map[string]string)
        m.lock = new(sync.RWMutex)
}

mais je me demande, s'il est possible de se débarrasser de ce boilerplate initialisant?

52
demandé sur Illarion Kovalchuk 2010-12-21 14:58:09

3 réponses

Vous avez juste besoin d'un constructeur. Un modèle couramment utilisé est

func NewSyncMap() *SyncMap {
    return &SyncMap{hm: make(map[string]string)}
}

dans le cas de plus de champs à l'intérieur de votre structure, en démarrant un goroutine comme backend, ou en enregistrant un finalizer, tout pourrait être fait dans ce constructeur.

func NewSyncMap() *SyncMap {
    sm := SyncMap{
        hm: make(map[string]string),
        foo: "Bar",
    }

    runtime.SetFinalizer(sm, (*SyncMap).stop)

    go sm.backend()

    return &sm
}
63
répondu Mue 2016-01-28 14:14:40

la solution de 'Mue' ne fonctionne pas puisque le mutex n'est pas initialisé. Les travaux de modification suivants:

package main

import "sync"

type SyncMap struct {
        lock *sync.RWMutex
        hm map[string]string
}

func NewSyncMap() *SyncMap {
        return &SyncMap{lock: new(sync.RWMutex), hm: make(map[string]string)}
}

func (m *SyncMap) Put (k, v string) {
        m.lock.Lock()
        defer m.lock.Unlock()
        m.hm[k] = v
}

func main() {
    sm := NewSyncMap()
    sm.Put("Test", "Test")
}

http://play.golang.org/p/n-jQKWtEy5

9
répondu deamon 2012-11-10 13:22:06

bonne prise par deamon. Mue pensait peut-être au modèle plus commun d'inclure la serrure comme une valeur plutôt qu'un pointeur. Comme la valeur zéro d'un Mutex est un Mutex déverrouillé prêt à l'emploi, il ne nécessite aucune initialisation et en inclure une comme valeur est courant. Comme une simplification supplémentaire, vous pouvez l'intégrer en omettant le nom du champ. Votre struct acquiert alors le jeu de méthode du Mutex. Voir cet exemple de travail, http://play.golang.org/p/faO9six-Qx . Aussi j'ai pris de l'utilisation de reporter. Dans une certaine mesure, il s'agit d'une question de préférence et de style de codage, mais comme il a un petit overhead, j'ai tendance à ne pas l'utiliser dans les petites fonctions, surtout s'il n'y a pas de code conditionnel.

5
répondu Sonia 2012-11-10 20:57:11