In Go, an interface is just a set of methods (spec: Interface types).
The interface does not specify whether receivers are pointers or not. Implementing an interface in Go is implicit: there is no declaration of intent.
You need to read and understand Method sets. Quoting an important part of it:
The method set of any other type T
consists of all methods declared with receiver type T
. The method set of the corresponding pointer type *T
is the set of all methods declared with receiver *T
or T
(that is, it also contains the method set of T
).
A value (which may or may not be a pointer) implements an interface if the method set of its type is a superset of the interface (the methods of the interface type).
In your example:
func (s *SomeStruct) SomeMethodWhichNeedsAPointerReceiver() string{}
SomeMethodWhichNeedsAPointerReceiver()
has a pointer receiver, so a value of type SomeStruct
will not have this method, but a value of type *SomeStruct
will.
So as a consequence a value of type SomeStruct
does not implement your SomeInterface
interface (because it does not have a SomeMethodWhichNeedsAPointerReceiver()
method), but *SomeStruct
does implement your SomeInterface
because its method set contains the SomeMethodWhichNeedsAPointerReceiver()
method.
Since you create and use a simple SomeStruct
value (and not a pointer to it), the type assertion will fail.
Should you have used a *SomeStruct
, the type assertion would have succeeded.
Modify your SomeThirdPartyMethod()
function to create and return a *SomeStruct
(a pointer) and it will work as you expect it:
func SomeThirdPartyMethod() interface{} {
return &SomeStruct{}
}
Or as an alternative:
func SomeThirdPartyMethod() interface{} {
return new(SomeStruct)
}
Try it on the Go Playground.
If you can't modify SomeThirdPartyMethod()
If you can't modify the SomeThirdPartyMethod()
function: first of all, is it intended/required that it returns a value which implements SomeStruct
? If so, then its current implementation is wrong, and you can expect it to return a value which does implement SomeStruct
without you having to dereference it (in order to gain a value which implements SomeStruct
).
In this specific case you can also try type assertion for SomeStruct
itself:
if ss, ok := s.(SomeStruct); ok {
fmt.Println(ss.SomeMethodWhichNeedsAPointerReceiver())
}
Calling ss.SomeMethodWhichNeedsAPointerReceiver()
will automatically dereference ss
to take its address (which will be the pointer receiver value for calling the SomeMethodWhichNeedsAPointerReceiver()
method).