5

am working in Golang, am trying to use interfaces to agroup a set of structs that are using a similar method. Briefly I have this:

type Person interface {
    BasicInfo() MemberBasicInfo
}

type MemberBasicInfo struct {
    ID                         uint       
    MemberFirstName            string     
    MemberNickname             string     
    MemberEmail                string    
}

Then, the structs that should work as interfaces:

func (member *Member) BasicInfo() MemberBasicInfo{
    return MemberBasicInfo{
        ID: member.ID,
        ...other mapping here...
    }
}

func (user *User) BasicInfo() MemberBasicInfo{
    return MemberBasicInfo{
        ID: uint(user.ID),
        ...other mapping here...
    }
}

cannot use memberData (type Member) as type Member.Person in return argument: Member does not implement Person (BasicInfo method has pointer receiver)
cannot use memberData (type User) as type Person in return argument: User does not implement Person (BasicInfo method has pointer receiver)

What am I missing? or what am I doing wrong?

Sredny M Casanova
  • 4,735
  • 21
  • 70
  • 115

2 Answers2

29

If your interface is declared like this:

type Person interface {
    BasicInfo() MemberBasicInfo
}

Then any type that implements a BasicInfo() MemberBasicInfo will fulfil the interface.

In your case, you then created this method:

func (member *Member) BasicInfo() MemberBasicInfo

That means that the type *Member fulfils the interface.

But.. note the * there. Member does not implement the interface, it is *Member who does.

So when trying to assign a type to an interface variable, make sure to use a pointer and not a direct value.

This should work:

var p Person
p = &Member{}

But this will not:

var p Person
p = Member{}
eugenioy
  • 11,825
  • 28
  • 35
  • Just wanna say this is the clearest and simplest explanation of "why" this error occurs generally that I've seen. – Benji L. Feb 02 '21 at 18:40
5

A pointer receiver requires you to assign pointers of a concrete class to variables of the interface type.

func usage() {
    var x Person

    // Notice the ampersand '&'
    x = &Member{}

    x.BasicInfo()
}
George Polevoy
  • 7,450
  • 3
  • 36
  • 61