I have a struct ProductData and its instance p which has a slice attribute :
type ProductInfo struct { TopAttributes []map[string]interface{} }
I want to set TopAttributes as follows
func (p *ProductInfo) setAttributeData() { key := "key" value := "value" setAttribute(p.TopAttributes, key, value) } func setAttribute(p []map[string]interface{}, key string, value interface{}) { val := map[string]interface{}{ key: value, } p = append(p, val) }
However, there is another way which works fine when I define a method as:
func (p *ProductInfo) setAttributeData() { key := "key" value := "value" p.setAttribute(key, value) } func (p *ProductInfo) setAttribute(key string, value interface{}) { val := map[string]interface{}{ key: value, } p.TopAttributes = append(p.TopAttributes, val) }
I want to find out why it is not working. There were no errors in my code, but the data coming was empty. I am trying to do this to make it a generic function as I have another BottomAttributes which has to be set the same way.
Go Pointers Slices are Pointers to Array Segments Slices are pointers to arrays, with the length of the segment, and its capacity. They behave as pointers, and assigning their value to another slice, will assign the memory address.
To add an element to a slice , you can use Golang's built-in append method. append adds elements from the end of the slice. The first parameter to the append method is a slice of type T . Any additional parameters are taken as the values to add to the given slice .
p = arr; // Points to the whole array arr. p: is pointer to 0th element of the array arr, while ptr is a pointer that points to the whole array arr. The base type of p is int while base type of ptr is 'an array of 5 integers'.
The * and & operators In Go a pointer is represented using the * (asterisk) character followed by the type of the stored value. In the zero function xPtr is a pointer to an int . * is also used to “dereference” pointer variables. Dereferencing a pointer gives us access to the value the pointer points to.
append
returns a reference to the appended-to slice. This is because it could point to a new location in memory if it needed to be resized.
In your first example, you are updating the variable passed to your setAttribute
function, but that's it. The only reference is lost when that function exits.
It works in the second example because that variable lives in your struct, and is thus updated.
You can fix the first version by using a pointer:
func (p *ProductInfo) setAttributeData() { key := "key" value := "value" setAttribute(&p.TopAttributes, key, value) } func setAttribute(p *[]map[string]interface{}, key string, value interface{}) { val := map[string]interface{}{ key: value, } *p = append(*p, val) }
You are trying to append a map
value which is used as a function parameter, so it has a local scope, accessible only within the function. Because this is referenced by value and not by pointer address, it's access is restricted only to it's local scope.
Map types are reference types, like pointers or slices, and so the value of parameter p
is nil; it doesn't point to an initialized map.
To point it to a map you have to access trough it's pointer:
func (p *ProductInfo) setAttributeData() { key := "key" value := "value" setAttribute(p.TopAttributes, key, value) } func setAttribute(p *[]map[string]interface{}, key string, value interface{}) { val := map[string]interface{}{ key: value, } *p = append(*p, val) }
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