I am new to Golang so allocation in it makes me insane:
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 }
and later, I just call:
sm := new(SyncMap) sm.Put("Test, "Test")
At this moment I get a nil pointer panic.
I've worked around it by using another one function, and calling it right after new()
:
func (m *SyncMap) Init() { m.hm = make(map[string]string) m.lock = new(sync.RWMutex) }
But I wonder, if it's possible to get rid of this boilerplate initializing?
You just need a constructor. A common used pattern is
func NewSyncMap() *SyncMap { return &SyncMap{hm: make(map[string]string)} }
In case of more fields inside your struct, starting a goroutine as backend, or registering a finalizer everything could be done in this constructor.
func NewSyncMap() *SyncMap { sm := SyncMap{ hm: make(map[string]string), foo: "Bar", } runtime.SetFinalizer(sm, (*SyncMap).stop) go sm.backend() return &sm }
The solution of 'Mue' doesn't work since the mutex is not initialized. The following modification works:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With