分配和初始化 Go 结构对于新手来说可能很棘手。考虑这个例子:
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") }
此代码将因 nil 指针异常而崩溃,因为 lock 和 hm 未初始化。
要解决此问题,可以使用以下解决方法:
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") }
但这增加了不必要的样板。
更简洁的方法是使用构造函数来初始化结构。构造函数是返回结构的初始化实例的函数。例如:
func NewSyncMap() *SyncMap { return &SyncMap{hm: make(map[string]string)} }
此构造函数初始化 hm 字段,并返回指向新创建的 SyncMap 实例的指针。
func main() { sm := NewSyncMap() sm.Put("Test", "Test") }
现在,代码正确初始化结构体,无需任何样板.
构造函数模式还可以用于初始化多个字段、启动 goroutine 或为结构注册终结器。例如:
func NewSyncMap() *SyncMap { sm := SyncMap{ hm: make(map[string]string), foo: "Bar", } runtime.SetFinalizer(sm, (*SyncMap).stop) go sm.backend() return &sm }
这个构造函数初始化 hm 和 foo 字段,为 backend() 启动一个 goroutine,并注册一个终结器以在 SyncMap 实例被垃圾收集时运行 stop() 方法。
以上是构造函数模式如何解决Go结构体初始化问题?的详细内容。更多信息请关注PHP中文网其他相关文章!