I am trying to follow the Go proverb "Make the zero value useful" but run into an issue with private fields on my struct that are by default nil
(like map
). If the zero value of my struct is to be useful, at some point it needs to initialize the private field. Consider the following situation in which I would like to do away with the constructor for Response
, and make the zero value of Response
useful. Obviously the field bag
(which is a map[string]interface{}
) needs to be initialized. I try to initialize the field bag
when the getter Bag()
is called on Response, which works, and allows for then calling Set()
on the bag to set a value. But somehow when the response ends up back in the main function, my value gets lost.
I believe the problem is that the initialization that I came up with replaces the pointer on a copy of Response, instead of changing what the pointer points at. So the old pointer still points to nil
, but I am not sure. How to initialize the private field correctly without the constructor?
func main() {
response := getResponse()
number := response.Bag().Get("NiceNumber")
fmt.Println(response.Name, "tells me that your nice number today is:", number)
}
func getResponse() (response Response) {
response = newResponse() // I am trying to do away with this line.
response.Name = "MyResponse"
response.Bag().Set("NiceNumber", 100)
return
}
type Response struct {
Name string
bag Bag
}
func (r Response) Bag() Bag {
// I have added this piece of code as an attempt to initialize r.bag
if r.bag == nil {
r.bag = Bag(make(map[string]interface{}))
}
// ---
return r.bag
}
type Bag map[string]interface{}
func (b Bag) Set(name string, value interface{}) {
b[name] = value
}
func (b Bag) Get(name string) interface{} {
return b[name]
}
// This constructor would be deleted if possible.
func newResponse() Response {
return Response{
Name: "",
bag: Bag(make(map[string]interface{})),
}
}
Output now is MyResponse tells me that your nice number today is: 100
, and when I remove the call to the constructor of Response, the output is MyResponse tells me that your nice number today is: <nil>
.