Home > other >  Copying pointer content in go causing uneccesary overhead?
Copying pointer content in go causing uneccesary overhead?

Time:10-06

If I understood it right, *s = *(*State)(&state) copies the content at &state to the s address (after casting *rawState to *State). But if it is that way, wouldn't it be more efficient to just do s = (*State)(&state) instead of copying and *state being collected by GC? Or could it lead to side-effects changing the value of s / or other reasons for doing it this way? Thanks!

complete function from [0]:

func (s *State) UnmarshalJSON(b []byte) error {
type rawState State
var state rawState

dec := json.NewDecoder(bytes.NewReader(b))
if s.useJSONNumber {
    dec.UseNumber()
}
err := dec.Decode(&state)
if err != nil {
    return err
}

*s = *(*State)(&state)

return s.Validate()}

[0] https://github.com/hashicorp/terraform-json/blob/d1018bf93fd9c097133b0159ab8b3c0517a846c9/state.go#L73

CodePudding user response:

The assignment:

*s = *(*State)(&state)

Does copy the pointed value. This is required because s is a local variable, assigning anything to s itself will have no effect once the function returns.

The intention is to assign something where s points to, and that is what the above assignment statement does.

The goal of using rawState is to create a new type which does not have the UnmarshalJSON() method, so passing *rawState to json.Unmarshal() will not cause a stack overflow.

See related: Call json.Unmarshal inside UnmarshalJSON function without causing stack overflow

CodePudding user response:

s is a pointer lets say pointing to location x in memory.

&state is another pointer at memory location y.

the function UnmarshalJSON is called with pointer pointing to memory location x.

if you do:

*s = *(*State)(&state)

this means: take pointer to y(&state), convert it to the correct pointer type(*State), then go to memory location y(* at the beginning after =) and then copy the value(=), to this other memory location x(*s).

if you, on the other hand, do: s = (*State)(&state)

this means: take pointer to y(&state), convert it to correct pointer type(*State), copy that pointer(=) to receiver (s). The memory location x being pointed to by whatever called this function, remains unchanged.

Also when the method is called the pointer itself, received by UnmarshalJSON as s, is a copy of the pointer at the position it's called from. This s inside UnmarshalJSON is a value of type *State that does not exist beyond UnmarshalJSON. This assignment will hence be meaningless beyond UnmarshalJSON.

  • Related