Dereferencing var before returning it where it won't be modified

Hi,

The caller.go will never need to modify result var so I believe what I am doing in result.go by dereferencing result var is “good”. Am I correct to assume this? Came to conclusion after reading https://github.com/golang/go/wiki/CodeReviewComments#receiver-type

Also dereferencing (using the * operator) in Go doesn’t make a copy. It returns the value the pointer points to. This means it doesn’t allocate more space in memory. Is that correct?

Thanks

// result.go
func NewResult(user entity.User) Result {
	result := &Result{}

    // Updating all properties of `result` coming from `user`.
    // result.... = user....
    
	return *result
}
// caller.go
func main() {
    result := result.NewResult(User{//....})

    // Do something with `result` but don't modify it.
    
    fmt.Println(result)
}

That’ll work, but I’d typically

func NewResult(user entity.User) Result {
    var result Result

    // Updating all properties of `result` coming from `user`.
    // result.... = user....
    
	return result
}

skipping the pointer, or, directly

func NewResult(user entity.User) Result {
    return Result{
        // all the properties in Field: value form
    }
}

if the field values don’t require computation and stuff and it looks clear when written like that.

Maybe? I mean, the * itself probably won’t copy, but the result needs to end up somewhere. When returning the struct it needs to be on the stack. That stack space is allocated and zeroed by the caller so we need to copy our struct into it. (You can think of the return value itself as a special variable, where return result is similar to preallocatedReturnValue = result.) I would suspect all the above code fragments results in a memory copy (stack to stack), but memory copies are very cheap. None of them should result in a heap allocation, which is the thing to avoid, so that’s good. It’s also possible that the compiler optimizes this and just writes directly to the return value in all the cases above, but I wouldn’t count on it. And it doesn’t really matter anyway. :slight_smile:

1 Like

Here is an alternate solution that I assume will avoid a copy, unless it is already optimized by the compiler.

 func NewResult(user entity.User) (result Result) {
     // Updating all properties of `result` coming from `user`.
     // result.... = user....
    return
}
1 Like

@Christophe_Meessen @calmh

Thanks for the valuable input, all appreciated, helped and clarified questions.

The main reason why I asked this particular question is because, I often see people just passing/returning pointers to/from functions by default even though they don’t modify it. I am a learner so cannot have a strong argument against it at this level yet but I have a feeling that there is a bit of bad habit of overusing pointers blindly all over the place. I think most people follow “If in doubt, use a pointer” bit as mentioned here - which should actually read “If in doubt, you don’t know what you are doing” :grimacing:

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.