How to ensure that a Struct that is made up of channels and map gets passed by reference?

Issue

I have the following struct that contains channels and a map for storage of data. I want to be able to pass that struct into functions in order to make use of those channels so that once they are triggered/have incoming messages, to use them in order to update the map that is associated with it.

I understand that maps by default are passed by reference when sent to various functions. Would this be the same case even when they are contained within a custom struct? How do i make sure that my entire struct is passed around to functions by reference in order to update Storage and also make use of its channels?

type CustomStrct struct {
Storage      map[string]string
RetrieveChannel    chan string
InsertChannel      chan string
}

This is a constructor I have created for initialising a new instance of the struct:

func InitializeNewStore() CustomStrct {
    newCustomStruct := CustomStrct {
        Storage:      make(map[string]string),
        RetrieveChannel:    make(chan Request),
        InsertChannel:    make(chan Request),
       }
 
return newCustomStruct 
}

Solution

Slices, maps and channels are pointer-like values in Go: copying a struct containing a channel copies a reference to the channel, not the channel itself:

a := CustomStrct{
    RetrieveChannel: make(chan Request),
}
b := a
log.Println(a.RetrieveChannel == b.RetrieveChannel)    // logs true

So it’s quite fine to pass your struct either by value or by reference.

If you need to ensure that go vet will flag attempts to pass your struct by value, the simplest solution is to embed a sync.Mutex inside the struct:

type CustomStrct struct {
    mu sync.Mutex
    ...
}

You don’t need to actually use the mutex: just having it embedded in the struct will cause go vet to complain whenever you attempt to pass it by value.

Answered By – jch

Answer Checked By – Willingham (GoLangFix Volunteer)

Leave a Reply

Your email address will not be published.