"<type> is pointer to interface, not interface" confusion

Viewed 90847

I have this problem which seems a bit weird to me. Take a look at this snippet of code:

package coreinterfaces

type FilterInterface interface {
    Filter(s *string) bool
}

type FieldFilter struct {
    Key string
    Val string
}

func (ff *FieldFilter) Filter(s *string) bool {
    // Some code
}

type FilterMapInterface interface {
    AddFilter(f *FilterInterface) uuid.UUID     
    RemoveFilter(i uuid.UUID)                   
    GetFilterByID(i uuid.UUID) *FilterInterface
}

type FilterMap struct {
    mutex   sync.Mutex
    Filters map[uuid.UUID]FilterInterface
}

func (fp *FilterMap) AddFilter(f *FilterInterface) uuid.UUID {
    // Some code
}

func (fp *FilterMap) RemoveFilter(i uuid.UUID) {
    // Some code
}

func (fp *FilterMap) GetFilterByID(i uuid.UUID) *FilterInterface {
    // Some code
}

On some other package, I have the following code:

func DoFilter() {
    fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"}
    filtermap := &coreinterfaces.FilterMap{}
    _ = filtermap.AddFilter(fieldfilter) // <--- Exception is raised here
}

The run-time won't accept the line mentioned because

"cannot use fieldfilter (type *coreinterfaces.FieldFilter) as type *coreinterfaces.FilterInterface in argument to fieldint.AddFilter: *coreinterfaces.FilterInterface is pointer to interface, not interface"

However, when changing the code to:

func DoBid() error {
    bs := string(b)
    var ifilterfield coreinterfaces.FilterInterface
    fieldfilter := &coreinterfaces.FieldFilter{Key: "app", Val: "152511"}
    ifilterfield = fieldfilter
    filtermap := &coreinterfaces.FilterMap{}
    _ = filtermap.AddFilter(&ifilterfield)
}

Everything is alright and when debugging the application it really seems to include

I'm a bit confused on this topic. When looking at other blog posts and stack overflow threads discussing this exact same issue (for example - This, or This) the first snippet which raises this exception should work, because both fieldfilter and fieldmap are initialized as pointers to interfaces, rather than value of interfaces. I haven't been able to wrap my head around what actually happens here that I need to change in order for me not to declare a FieldInterface and assign the implementation for that interface. There must be an elegant way to do this.

2 Answers
GetFilterByID(i uuid.UUID) *FilterInterface

When I get this error, it's usually because I'm specifying a pointer to an interface instead of an interface ( that will actually be a pointer to my struct that fulfills the interface ).

There's a valid use for *interface{...} but more commonly I just am thinking 'this is a pointer' instead of 'this is an interface which happens to be a pointer in the code I'm writing'

Related