Golang抽象接口切片转换

我有一个对象列表(准确地说是 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.go

type 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': ''

    }    

  ]

}


手掌心
浏览 302回答 3
3回答

胡说叔叔

如果我理解正确,您想将数据解组为两种类型的切片: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 typevar s1 []TypeAif err := executeQuery(q1, &s1); err != nil {    // handle error}// Slice of pointer to typevar s2 []*TypeBif err := error(q2, &s2); err != nil {   // handle error}我知道这不是问题的直接答案,但这就是通常处理这种情况的方式。

阿晨1998

我不相信这很容易做到。在godocs的原始消息示例中,他们使用 json 中的一个值,在他们的示例中为“Space”,以确定要解组的结构类型。为此,该函数必须有某种方法来获取为程序定义的每个结构体,然后它必须检查每个 json 对象并使用反射将其与每个结构体进行比较以找出它的类型最有可能的是。如果有多个“可能”的结构呢?然后冲突解决使事情复杂化。简而言之,我不认为你可以做到这一点。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go