-2

How do i convert from map[string] MyStruct to map[string] MyInterface, when MyStruct implements MyInterface.

type MyInterface interface {
    Say() string
}

var MyInterfaceMap map[string] MyInterface

type MyStruct struct{
    Message string
}

func (myStruct *MyStruct) Say() string{
    return myStruct.Message
}

func Init() {
    data := []byte(`{"greet":{"Message":"Hello"}}`)
    myStructMap := make(map[string] MyStruct )
    _ = json.Unmarshal( data, &myStructMap)
    MyInterfaceMap = myStructMap 
}
JonPen
  • 113
  • 6
  • 2
    https://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go read the answers there, although it's about converting the elements of a slice, same constraints apply to maps. – mkopriva Mar 06 '18 at 19:05
  • 1
    Possible duplicate of [Type converting slices of interfaces in go](https://stackoverflow.com/questions/12753805/type-converting-slices-of-interfaces-in-go) – Jonathan Hall Mar 07 '18 at 08:49

1 Answers1

1

Once unmarshalled, copy the map to MyInterfaceMap like below

package main

import (
    "encoding/json"
    "fmt"
    "reflect"
)

type MyInterface interface {
    Say() string
}

var MyInterfaceMap map[string]MyInterface

type MyStruct struct {
    Message string
}

func (myStruct *MyStruct) Say() string {
    return myStruct.Message
}

func main() {
    data := []byte(`{"greet":{"Message":"Hello"}}`)
    myStructMap := make(map[string]MyStruct)
    err := json.Unmarshal(data, &myStructMap)
    if err != nil {
        panic(err)
    }

    MyInterfaceMap = make(map[string]MyInterface)
    for k, v := range myStructMap {
        MyInterfaceMap[k] = &v
    }
    fmt.Println(reflect.TypeOf(MyInterfaceMap))
    fmt.Println(MyInterfaceMap)
}

And the result would be

map[string]main.MyInterface
map[greet:0x1050c1a0]
vedhavyas
  • 1,101
  • 6
  • 12
  • Sure that's an acceptable work around but why cant i assert / cast the map of concrete types to a map of interface the type implements. Or in other words whats the special magic way go can tell the difference between map[string] MyInterface and map[string] *MyStruct. – JonPen Mar 06 '18 at 18:59
  • I'm actually doing the same in the for loop. Concrete type to an interface. – vedhavyas Mar 06 '18 at 19:02
  • take a look at the interface section in here - https://divan.github.io/posts/avoid_gotchas/ – vedhavyas Mar 06 '18 at 19:04
  • that gotch link doesn't explain much "We’re not going to learn the logic of how interface type assertion works". The fact is it should work you work-around proves they are equivalent you should just be able to assert, providing that the map is a map to pointers to a struct. – JonPen Mar 06 '18 at 19:23