Is there a performance penalty for passing "this" by value in Go methods?

c++, go

Solution

The other answers are good but in my opinion, there's some information missing.

Receivers in Go are just syntactic sugar, as demonstrated by the following code:

package main

import "fmt"

type Something struct {
    Value int
}

func (s *Something) ChangeValue(n int) {
    s.Value = n
}

func main() {
    o := new(Something)             // o is of type *Something
    fmt.Println(o.Value)            // Prints 0
    o.ChangeValue(8)                // Changes o.Value to 8
    fmt.Println(o.Value)            // Prints 8
    (*Something).ChangeValue(o, 16) // Same as calling o.ChangeValue(16)
    fmt.Println(o.Value)            // Prints 16
}

Based on this, consider what would happen if the receiver of `ChangeValue` was a value of type `Something` instead of a pointer to one...

That's right! You could never actually mutate `o`'s `Value` field through this method. Most of the time, you use pointer receivers to do encapsulation.

Problem

I'm exploring Go after 9 years of C++ development. In C++ it is a bad practice to pass function's arguments by value except variables of built-in types because of performance penalty: all fields of the argument will be copied and in most cases it will be a very costly operation. Is this true for Go? It looks very expensive to pass "this" by value only to assign "const" semantic to the method. Is Go compiler smart enough to prevent variable from being copied before first modification? Why isn't passing "this" by value an anti-pattern in Go as it is in C/C++?

Original source