在golang中存储和检索接口

时间:2018-06-30 08:09:54

标签: json go protocol-buffers

我们如何将不同结构的数组存储到某个文件中,并以相同的格式将其取回而又不丢失其属性(其提供的方法)。

例如:我有数据struct Astruct B,它们都通过某些方法实现了公用的interface X {}

一个选项是编写保存和检索方法以接受接口X slice。

但是,问题在于如何以某种通用方式将其解组,这与我的Data结构无关。即,每次添加新的数据结构时,都不需要更改保存或检索函数来检索接口X的切片,以便可以独立于数据结构使用其方法。

解组引发错误的示例:

Go PlayGround Link with a small Example

3 个答案:

答案 0 :(得分:0)

有趣的问题,如沃尔克尔(Volkel)所说,可以随心所欲地解决。但是,当您重新设计时,就有可能。通常,请尝试避免使用反射。它不是惯用语言,但是在某些情况下它非常强大,也许正是您要查找的东西,尤其是,通常没有太多适用于结构的候选对象,您可以在应用程序内部保留其参数中具有泛型的unmarshall方法,因为类型发现过程在函数内部,而在函数调用中不可见。

因此有时候,您可以在UnMarshall函数中使用它来解决它。

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

答案 1 :(得分:0)

  

但是问题是如何以某种通用方式将其解组,这与我的Data结构无关。

是的,这是不可撤消的。重新设计。

答案 2 :(得分:0)

如果只考虑数据,则更容易...

您的X不应是接口,而应是结构,以便您可以封送它。

要使流程通用,可以考虑X拥有选择权

type A struct {
    A int64
}

type B struct {
    S string
}

type Choice int

const (
    XisA Choice = iota
    XisB
)

type X struct {
    Choice
    A
    B
}

编组之前,您只需要为数组中的每个项目设置选择

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}

解组后,您只需要检索对数组的每个项目所做的选择

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

这里是一个示例:https://play.golang.org/p/RtzF6DmNlKL