在golang中存储和检索接口

How can we store array of different structs into some file and retrieve it back in the same format without losing its properties(methods it provides).

For example: I have data struct A and struct B, both implementing a common interface X {} with some methods.

One options is to write both save and retrieve method to accept the interface X slice.

However the problem is how to unmarshal it back in some generic way which is not tied to my Data struct. i.e., every time I add a new data struct I need not to change my save or retrieve functions to retrieve back the slice of interface X so that its methods can be used independent of data struct.

Example where Unmarshaling throws error :

Go PlayGround Link with a small Example

Intersting question, like Volkel says, undoable as you want it. But as you redesign then there are possibilities. Normally, try to avoid using reflection. It’s not idiomatic, but it’s very powerful in particular cases and it maybe just what you are looking for, especially, often there are not many candidates for structs which are applicable, and you can keep inside your application the unmarshall method generic in its parameter, because the type-discovery procedure is inside the function, and not visible in the function call.

So sometimes, you can solve it by using it inside the UnMarshall function.

if (f.Type() == reflect.TypeOf(Entity{})) {
  //reflected type is of type "Entity", you can now Unmarshal
}

However the problem is how to unmarshal it back in some generic way which is not tied to my Data struct.

Yes, this is undoable. Redesign.

It is easier if you think only of the data ...

Your X should not be an interface but a struct so that you can marshall it.

To make the process generic, you can consider X holds a choice

type A struct {
    A int64
}

type B struct {
    S string
}

type Choice int

const (
    XisA Choice = iota
    XisB
)

type X struct {
    Choice
    A
    B
}

Before marshalling, you just need to set the choice for each item of your array

a := A{
    A: 1,
}

b := B{
    S: "2",
}

x1 := X{
    Choice: XisA,
    A:      a,
}
x2 := X{
    Choice: XisB,
    B:      b,
}
x := [2]X{x1, x2}

After unmarshalling, you just need to retrieve the choice you made for each item of the array

for _, item := range decoded {
    switch {
    case item.Choice == XisA:
        println(item.A.GetKey())
    case item.Choice == XisB:
        println(item.B.GetKey())
    }
}

Here is an example: https://play.golang.org/p/RtzF6DmNlKL