2

The title is a little hard to parse so here's more verbose, understandable example:

import "fmt"
import "reflect"

type Stringer interface {
    String() string
}

type MyInt int

func (m MyInt) String() string {
    return fmt.Sprintf("I'm number %d!", m)
}

func main() {
    var m = MyInt(10)
    m_type := reflect.TypeOf(m)

    m_type.Implements(reflect.TypeOf(Stringer(nil))) // This does not work.
}

If you try this code, you will get a panic from within reflect.[some internal class].Implements. Why doesn't this work? Is this some weird side effect of typed nil and nil interfaces?

What's the best workaround for it? I've seen this in the wild:

m_type.Implements(reflect.TypeOf((*Stringer)(nil).Elem())) // true

It works, but it's ugly as hell. Is there a cleaner way? Why does this work when the naive approach does not?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Wug
  • 12,956
  • 4
  • 34
  • 54
  • 1
    https://github.com/golang/go/issues/35427 –  Jul 23 '21 at 14:06
  • 1
    there is super long exaplanations by icza https://stackoverflow.com/a/29138676/4466350 see if that helps. –  Jul 23 '21 at 14:12
  • Am i the only one thnking that even after reading in depth description about that behavior i still lack a piece of understanding to make it clear about what happens ? –  Jul 23 '21 at 15:39
  • @thwd I think, my diffculty is that i dont understand why in case 1 the underlying type is retained, but in the second case it is lost. I am figuring this is something related to the way things are represented in memory, but, unclear to me. My understanding is that a variable can ever only have one interface "hint type" at a time, thus for variable i, when its Stringer value is assigned, it ends up with only a pointer to empty interface, rather than, empty interface => stringer+nil https://play.golang.org/p/JCZxxtAVVvZ –  Jul 24 '21 at 09:21

0 Answers0