gobackwards-compatibility

In go, is it backwards compatible to change a receiver struct from a value to a pointer?


Starting with code like:

type Foo struct {
    V bool
}

func (f Foo) bar() bool {
    return f.V
}

Is it allowed to change to func (f *Foo) bar() bool without incrementing the major version number? That is, assuming you know there are no thread safety issues with your type. If so, the reverse change is allowed too, correct?

Any code that called the function regardless of whether the variable was a value or a pointer would continue to compile and work as expected after both changes, as far as I can tell.


Solution

  • As per the comments, this answer answer provides a good summary T vs *T receiver types. Following are a couple of examples where a change from func (f Foo) bar() bool to func (f *Foo) bar() bool would break existing code.

    Example 1: T is not addressable (playground):

    type Foo struct {
        V bool
    }
    
    func (f *Foo) bar() bool { // Change to `(f Foo)` and this will work
        return f.V
    }
    
    func x() Foo {
        return Foo{true}
    }
    
    func main() {
        fmt.Printf("%v", x().bar())
    }
    

    Example 2: Interface (playground):

    type Foo struct {
        V bool
    }
    
    func (f *Foo) bar() bool { // Change to `(f Foo)` and this will work
        return f.V
    }
    
    type Fooer interface {
        bar() bool
    }
    
    func main() {
        var x Fooer
        x = Foo{}
        fmt.Println(x.bar())
    }