0

I found two questions and read them:

But I still don't understand why I tried mapping an Object that got error:

./aaa.go:21: m.Action undefined (type interface {} is interface with no methods)

type MyStruct struct {
}

func (a *MyStruct) Action() {
    fmt.Println("Hello")
}

func main() {
    var Mstruct map[string]interface{}
    Mstruct = make(map[string]interface{}, 100)
    Mstruct["MyStruct"] = &MyStruct{}
    m := Mstruct["MyStruct"]
    fmt.Println(reflect.TypeOf(m)) // *main.MyStruct
    m.Action()
}

This always works in dynamic language, so I miss something in static language.

Community
  • 1
  • 1
Muge
  • 469
  • 5
  • 11

2 Answers2

3

The expression

m := Mstruct["MyStruct"]

is a short variable declaration. The specification states

If a type is present, each variable is given that type. Otherwise, each variable is given the type of the corresponding initialization value in the assignment.

Since a type is not present in that expression, the variable m is given the type of the corresponding initialization value, Mstruct["MyStruct"]. That type is interface{}.

Based on your current imports, the method set of interface{} is empty. There's nothing you can invoke on a value of ype interface{}. Therefore the compiler rejects

m.Action()

You seem to want to use m as a method receiver based on its dynamic type, *MyStruct. You can do that with a type assertion. For example

dynamic := m.(*MyStruct)
dynamic.Action()

The specification states

If the type assertion holds, the value of the expression is the value stored in x and its type is T.

Its type here is *MyStruct which is the receiver type of your Action method. You can therefore invoke the method with the variable dynamic.

Savior
  • 3,225
  • 4
  • 24
  • 48
2
func main() {
    var Mstruct map[string]interface{}
    Mstruct = make(map[string]interface{}, 100)
    Mstruct["MyStruct"] = &MyStruct{}
    m := Mstruct["MyStruct"].(*MyStruct) //This is a type assertion
    fmt.Println(reflect.TypeOf(m)) // *main.MyStruct
    m.Action()
}

Use type assertion. After you assert that it is not nil and of the specified type, you can treat it as that type.

https://golang.org/ref/spec#Type_assertions

https://play.golang.org/p/bJib9g7kDY

saarrrr
  • 2,754
  • 1
  • 16
  • 26