Home >Backend Development >Golang >How Can the Constructor Pattern Solve Go Struct Initialization Problems?

How Can the Constructor Pattern Solve Go Struct Initialization Problems?

Linda Hamilton
Linda HamiltonOriginal
2024-12-02 04:04:14732browse

How Can the Constructor Pattern Solve Go Struct Initialization Problems?

Constructor Pattern for Initializing Go Structs

Allocating and initializing Go structs can be tricky for newcomers. Consider this example:

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")
}

This code will panic with a nil pointer exception because lock and hm are not initialized.

To address this, the following workaround can be used:

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")
}

But this adds unnecessary boilerplate.

The Constructor Pattern

A cleaner approach is to use a constructor function to initialize the struct. A constructor is a function that returns an initialized instance of a struct. For example:

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

This constructor initializes the hm field, and returns a pointer to the newly created SyncMap instance.

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

Now, the code initializes the struct correctly without any boilerplate.

The constructor pattern can also be used to initialize multiple fields, start goroutines, or register finalizers for the struct. For example:

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

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

    go sm.backend()

    return &sm
}

This constructor initializes both hm and foo fields, starts a goroutine for backend(), and registers a finalizer to run the stop() method when the SyncMap instance is garbage collected.

The above is the detailed content of How Can the Constructor Pattern Solve Go Struct Initialization Problems?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn