2

I have defined a Type

type UnknownMapString map[string]interface{}

I also have methods for them like so

func (m UnknownMapString) Foo() {
    fmt.Println("test!")
}

I get a panic when running:

interface conversion: interface is map[string]interface {}, not main.UnknownMapString

The map[string]interface{} is unmarshaled from JSON input.

Playground replicating it -> http://play.golang.org/p/kvw4dcZVNH

I thought that you could not have interface as a receiver of method so we needed to type assert (not convert?) to a Named Type and use that Named Type as the receiver of the method. Please let me know what I'm doing wrong. Thanks!

ansonl
  • 786
  • 1
  • 13
  • 34

1 Answers1

5
val = val.(UnknownMapString)

This is a type assertion, which supposes the named type UnknownMapString is identical to the unnamed type map[string]interface{}.
And type identity tells us that:

A named and an unnamed type are always different.

But: you can assign a map[string]interface{} to a UnknownMapString because

x is assignable to a variable of type T ("x is assignable to T") when:

x's type V and T have identical underlying types and at least one of V or T is not a named type.

This would work:

var val2 UnknownMapString  = val.(map[string]interface{})
val2.Foo()

val2 is not an unnamed type, and both val2 and val.(map[string]interface{}) underlying types are identical.

play.golang.org

Output:

test!
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • Thanks, so there is no way to have the original interface{} `val` equal the `UnknownMapString` type variable? Also, `map[string]interface{}` is unnamed because it composes type from existing types? GoDocs say unnamed "composes a new type from existing types". Existing types mean ONLY built in types and not a defined type that I make correct? – ansonl Aug 02 '14 at 05:37
  • @AnsonL yes, no way. `map[string]interface{}` is unnamed because it simply is a description corresponding to how that type is to be structured. – VonC Aug 02 '14 at 05:39
  • @AnsonL so you need to work with `var val2 UnknownMapString`, not directly with `val`. – VonC Aug 02 '14 at 05:40
  • "A description corresponding to how type is structured"? So `map[string]interface{}` is unnamed because how it is structured because creators of Go made it that way? Am I correct in assuming that **only** built in types of ArrayType, StructType, PointerType, FunctionType, InterfaceType, SliceType, MapType, ChannelType are unnamed? – ansonl Aug 02 '14 at 06:26
  • 1
    @AnsonL you can see more at http://stackoverflow.com/a/19334952/6309 and http://golang.org/ref/spec#Types: named types are specified by a (possibly qualified) type name; unnamed types are specified using a type literal, which composes a new type from existing types. You need a **identifier**, the type name, to bind to a type. – VonC Aug 02 '14 at 06:29