为了账号安全,请及时绑定邮箱和手机立即绑定

Golang抽象接口切片转换

Golang抽象接口切片转换

Go
手掌心 2021-09-27 16:08:01
我有一个对象列表(准确地说是 olievere/Elastic SearchResult.Hits)。其中每一个都有一个json.RawMessage对象,我希望创建一个可抽象的方法,该方法接受任何结构的接口切片,Unmarshal 将每个单独的命中“json.RawMessage放入所述结构中,并将其附加到传入的[]interface.这个 func 不应该对所需的业务层结构有任何逻辑或洞察力,而且 DB Call 的接口非常多,因此无法看到上面提到的 Elastic 包。我试图做的例子......foo.go    import (bar, package)type TestStruct struct {        Slice []*package.Struct // package.Struct has a value of Source which is a                                // json.RawMessage    }    func GetData() bar.Test {    return &TestStruct{*package.GetData()}}func (result TestStruct) UnmarshalStruct(v []interface{}) {        for _, singleStruct := range result.Slice {             append(json.Unmarshal(singleStruct, &v))    }第二个文件bar.gotype Handler interface {    GetData() Test}type Test interface {    UnmarshalStruct}type OtherType struct {   foo string   bar string} func RetrieveData() []OtherType {    handler := New(Handler)    test := handler.GetData()    var typeSlice []OtherType        test.UnmarshalStruct(&typeSlice)}我正在寻找某种类型的东西[]OtherType,或者我决定创建的任何其他新结构UnmarshalStruct,并让它返回给我相同的结构,只是充满数据例如,我要从 Elastic 搜索两种不同类型的数据。我将收到以下两个对象之一的列表。{ 'foo': '',  'id': }并且在不同的索引中{ 'bar': '',  'baz': '',  'eee': ''}     这些中的每一个自然需要两个不同的结构。但是,我希望有一种方法能够解码这些列表中的任何一个。我将在下面给出,并使用相同的函数将其转换为bar结构,并将其他类型转换为foo结构。{ 'source': [    { 'bar': '',      'baz': '',      'eee': ''    },    { 'bar': '',      'baz': '',      'eee': ''    },    { 'bar': '',      'baz': '',      'eee': ''    }      ]}
查看完整描述

3 回答

?
胡说叔叔

TA贡献1804条经验 获得超8个赞

如果我理解正确,您想将数据解组为两种类型的切片:


type A struct {

  Foo string `json:"foo"`

  ID string `json:"id"`

}


type B struct {

   Bar string `json:"bar"`

   Baz string `json:"baz"`

   Eee string `json:"eee"`

}

来自SearchHit Source。


JSON 包可以为您完成大部分工作:


func executeQuery(q Query, v interface{}) error {

   // Get a SearchHit. I am making this up. 

   // I have no idea how the package works.

   searchHit, err := getHit(q) 

   if err != nil {

      return err

   }

   // This is the important part. Convert the raw message to 

   // a slice of bytes and decode to the caller's slice.

   return json.Unmarshal([]byte(*searchHit.Source), v)

}

您可以调用此函数以解码为类型切片或指向类型的指针切片。


// Slice of type

var s1 []TypeA

if err := executeQuery(q1, &s1); err != nil {

    // handle error

}


// Slice of pointer to type

var s2 []*TypeB

if err := error(q2, &s2); err != nil {

   // handle error

}

我知道这不是问题的直接答案,但这就是通常处理这种情况的方式。


查看完整回答
反对 回复 2021-09-27
?
阿晨1998

TA贡献2037条经验 获得超6个赞

我不相信这很容易做到。在godocs的原始消息示例中,他们使用 json 中的一个值,在他们的示例中为“Space”,以确定要解组的结构类型。

为此,该函数必须有某种方法来获取为程序定义的每个结构体,然后它必须检查每个 json 对象并使用反射将其与每个结构体进行比较以找出它的类型最有可能的是。如果有多个“可能”的结构呢?然后冲突解决使事情复杂化。

简而言之,我不认为你可以做到这一点。


查看完整回答
反对 回复 2021-09-27
  • 3 回答
  • 0 关注
  • 301 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信