Interface method doesn't work with pointer receiver any more?

17,928 views
Skip to first unread message

AllenDang

unread,
Dec 30, 2011, 5:22:36 AM12/30/11
to golang-nuts
type Shower interface {
Show()
}

type S1 struct {
}

func (this *S1) Show() {
println("Show from S1")
}

func InvokeShow(s Shower) {
if s1, ok := s.(S1); ok {
s1.Show()
}
}

func main() {
var s1 S1
InvokeShow(s1)
}

It just doesn't work anymore! Error message is "S1 does not implement
Shower (Show method requires pointer receiver)".

David Symonds

unread,
Dec 30, 2011, 5:31:41 AM12/30/11
to AllenDang, golang-nuts
On Fri, Dec 30, 2011 at 9:22 PM, AllenDang <alle...@gmail.com> wrote:

> It just doesn't work anymore! Error message is "S1 does not implement
> Shower (Show method requires pointer receiver)".

Your example makes little sense from several angles, but the error is
accurate: S1 is not a Shower, but *S1 is. Pass &s1 to InvokeShow.


Dave.

Yves Junqueira

unread,
Dec 30, 2011, 5:31:51 AM12/30/11
to AllenDang, golang-nuts
You should use *S1 not S1.


On Fri, Dec 30, 2011 at 11:22 AM, AllenDang <alle...@gmail.com> wrote:
type Shower interface {
   Show()
}

type S1 struct {
}

func (this *S1) Show() {
   println("Show from S1")
}

func InvokeShow(s Shower) {
   if s1, ok := s.(S1); ok {

if s1, ok := s.(*S1); ok {
 
       s1.Show()
   }
}

func main() {
   var s1 S1
   InvokeShow(s1)

   InvokeShow(&s1)
 
}

It just doesn't work anymore! Error message is "S1 does not implement
Shower (Show method requires pointer receiver)".



--
Yves Junqueira <http://cetico.org/about>

AllenDang

unread,
Dec 30, 2011, 5:33:58 AM12/30/11
to golang-nuts
I tested it, pass &s1 to InvokeShow, error message changes to
"impossible type assertion: s (type Shower) cannot have dynamic type
S1 (missing Show method)".

On Dec 30, 6:31 pm, David Symonds <dsymo...@golang.org> wrote:

AllenDang

unread,
Dec 30, 2011, 5:36:02 AM12/30/11
to golang-nuts
Yes, you are correct! It works. Thanks very much!

On Dec 30, 6:31 pm, Yves Junqueira <yves.junque...@gmail.com> wrote:
> You should use *S1 not S1.
>
> http://play.golang.org/p/Y9-RgZHrZx
>

David Symonds

unread,
Dec 30, 2011, 5:48:23 AM12/30/11
to AllenDang, golang-nuts
On Fri, Dec 30, 2011 at 9:33 PM, AllenDang <alle...@gmail.com> wrote:

> I tested it, pass &s1 to InvokeShow, error message changes to
> "impossible type assertion: s (type Shower) cannot have dynamic type
> S1 (missing Show method)".

Again, the error message is telling you *exactly* what is wrong. You
are doing a type assertion of s to S1, and the compiler is saying that
that's impossible. You could change the type assertion to *S1, since
that is the type that you're passing around.


Dave.

Kyle Lemons

unread,
Jan 1, 2012, 6:12:04 PM1/1/12
to AllenDang, golang-nuts
The Method Sets wiki page ( http://code.google.com/p/go-wiki/wiki/MethodSets ) may help you understand what's going on here a bit better.

Drew Wells

unread,
Jan 11, 2014, 10:27:33 PM1/11/14
to golan...@googlegroups.com, AllenDang
Inline with the original subject, how do you do this?



func main() {
   var s1 S1
   Shower(s1).Show()

Kevin Gillette

unread,
Jan 11, 2014, 10:33:09 PM1/11/14
to golan...@googlegroups.com, AllenDang
S1 is not a Shower, but *S1 is. The following works: <http://play.golang.org/p/-51xx9lx0v>

Drew Wells

unread,
Jan 14, 2014, 10:52:18 AM1/14/14
to Kevin Gillette, golan...@googlegroups.com, AllenDang
Oh wow, my mind is blown.  Is this due to some limitation of interface in translating values to points properly for pointer receivers?


--
You received this message because you are subscribed to a topic in the Google Groups "golang-nuts" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/golang-nuts/-ZoCu5m0kJ4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

minux

unread,
Jan 14, 2014, 3:54:23 PM1/14/14
to Drew Wells, Kevin Gillette, golang-nuts, AllenDang
On Tue, Jan 14, 2014 at 10:52 AM, Drew Wells <drew.w...@gmail.com> wrote:
Oh wow, my mind is blown.  Is this due to some limitation of interface in translating values to points properly for pointer receivers?
It's easier to understand if you take these two factors into account, see http://play.golang.org/p/PUuOBZ4uM-
1. method set difference of pointer receiver and a regular receiver, this explains why InvokeShow
function has to type assert it argument to (*S1), not simply S1, and also why the main has to
pass (&s1) to InvokeShow.
2. the compiler will automatically take the pointer of the s1 in main in s1.Show() when it can.

Steven Blenkinsop

unread,
Jan 14, 2014, 10:16:19 PM1/14/14
to Drew Wells, Kevin Gillette, golang-nuts, AllenDang
On Tue, Jan 14, 2014 at 10:52 AM, Drew Wells <drew.w...@gmail.com> wrote:
Oh wow, my mind is blown.  Is this due to some limitation of interface in translating values to points properly for pointer receivers?
 
On one level, it's because the language spec says so. But ultimately, yes, it's because of a limitation on getting a pointer to pass as the receiver. You can't take the address of the value inside an interface, since its type could change (you could assign a differently typed value to the interface), among other reasons. So, if you need a pointer receiver, the pointer itself needs to be in the interface.

ioan.vap...@gmail.com

unread,
Mar 24, 2015, 12:23:08 PM3/24/15
to golan...@googlegroups.com, drew.w...@gmail.com, extempor...@gmail.com, alle...@gmail.com
I don't think the check "if s1, ok := s.(*S1); ok {" is necessary in you example since the compiler won't let you make in main the call "InvokeShow(s1)".

Nate Finch

unread,
Mar 24, 2015, 2:22:15 PM3/24/15
to golan...@googlegroups.com
I wrote about interfaces and how they work, maybe it will help you: http://npf.io/2014/05/intro-to-go-interfaces/

DhilipKumar Sankaranarayanan

unread,
Mar 25, 2015, 4:42:50 AM3/25/15
to golan...@googlegroups.com, drew.w...@gmail.com, extempor...@gmail.com, alle...@gmail.com
Slight addition to below code. 


Hope this helps,
Dhilip
Reply all
Reply to author
Forward
0 new messages