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!

1 Answer 1

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!
Sign up to request clarification or add additional context in comments.

5 Comments

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 yes, no way. map[string]interface{} is unnamed because it simply is a description corresponding to how that type is to be structured.
@AnsonL so you need to work with var val2 UnknownMapString, not directly with val.
"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 you can see more at stackoverflow.com/a/19334952/6309 and 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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.