#Update array member of struct through a pointer to an element in that array

13 messages · Page 1 of 1 (latest)

arctic mason
#

I don't seem to understand how pointers work.

My function getPodByName returns a pointer to a pod struct. By modifying this pod, I want to modify the global podList variable PL on which I run getPodByName to recieve the pointer.

My code below has comments that show desired output vs the output that I get.

Any help would be much appreciated!

package main

import (
    "fmt"
    "time"
)

var PL podList

type pod struct {
    name     string
    nodePort string
    state    string
}

func NewPodStruct() *pod {

    return &pod{
        name:     "UNAMED",
        state:    "UNEXPOSED",
        nodePort: "EMPTY",
    }

}

type podList struct {
    podArr           []pod
    namespace        string
    pod_name_stem    string
    statefulset_name string
    num_spawned      int
}

func (pl *podList) getPodByName(podNameFind string) *pod {

    var returnPod *pod

    for _, pod := range pl.podArr {
        if podNameFind == pod.name {
            returnPod = &pod
        }
    }
    return returnPod
}

func main() {

    newPod := NewPodStruct()
    newPod.name = "abc"

    PL.podArr = append(PL.podArr, *newPod)

    po := PL.getPodByName("abc")
    fmt.Printf("po: %v\n", po)
    // desired: po: &{abc EMPTY UNEXPOSED}
    // get: po: &{abc EMPTY UNEXPOSED}

    po.nodePort = "30777"

    po = PL.getPodByName("abc")
    fmt.Printf("po: %v\n", po)
    // desired: po: &{abc EMPTY 30777}
    // get: po: &{abc EMPTY UNEXPOSED}

}
nocturne raptor
#

If you need to change the value of the original pod, podList.podArr should be a []*pod

maiden sand
#

dereference the pointer to access and modify the struct

arctic mason
dawn solar
#

podArr in podList is an array of pods, not pod pointers

#

So when you append to that

#

You lose the thingy

vestal crown
# arctic mason I don't seem to understand how pointers work. My function `getPodByName` retu...

The issue here is that you do not understand what the pointer you are returning points to.
In for _, pod := range pl.podArr pod is a new variable that contains a copy of the current element.

In essence, what you are doing is no different than go func (pl *podList) getPodByName() *string { s := pl.namespace return &s }, here, you are not returning a pointer to pl.namespace, you are returning a pointer to a local variable s that contains a copy of pl.namespace.

So, in go for _, pod := range pl.podArr { if podNameFind == pod.name { returnPod = &pod } } you are not returning a pointer to the data stored in pl.podArr, you are returning a pointer to a local variable pod that contains a copy of what's stored in pl.podArr.

The simplest fix, assuming these are the exact semantics you're after and that there's not a better design for your problem in general, is to ensure you are returning a pointer to the contents of pl.podArr:

   for i, pod := range pl.podArr {
       if podNameFind == pod.name {
           returnPod = &pl.podArr[i]
       }
   }```
#

That said, I'm only answering on a technical level, on a design level there are many other things to consider, such as storing *pod, keeping them "immutable" and require an explicit api or assignment, etc.

arctic mason
vestal crown
#

I can't give concrete advice because I don't know 1) what the goal is, 2) what the program is supposed to do, and 3) how it's supposed to behave.

That said, I'd say the most obvious options would be to:
1 - like previously mentioned by others, store pointers and embrace the mutability, will bite you under concurrency
2 - don't store pointers and make mutability an api call, (in simpler terms, a store/save/update method. Which means mutations will only be visible to other callers when they next call getPodByName.

The fundamental question is: do you want mutable data or immutable data.
Mutability is very convenient, and just as surprising. Immutability is very cumbersome, and just as surprising. 🙃 There is no clear winner in the absence of context.

This is my opinion which I'm sure many people can find reasons to disagree with.

arctic mason