如何通过不同的结构来运作?

时间:2015-07-09 14:23:00

标签: go

我有几种不同的结构。

这里显示两个:

type AdsResponse struct {
    Body struct {
        Docs []struct {
            ID        int  `json:"ID"`
            // others

        } `json:"docs"`
    } `json:"response"`
    Header `json:"responseHeader"`
}

type OtherResponse struct {
    Body struct {
        Docs []struct {
            ID    int     `json:"ID"`
            // others
        } `json:"docs"`
    } `json:"response"`
    Header `json:"responseHeader"`
}

但我不知道我怎么做这个方法接受并返回两者。

func Get(url string, response Response) (Response, bool) {

    res, err := goreq.Request{
        Uri:         url,
    }.Do()

    // several validations

    res.Body.FromJsonTo(&response)

    return response, true
}

并像这样使用:

var struct1 AdsResponse
var struct2 OtherResponse

Get("someURL", struct1)
Get("someURL", struct2)

有什么形式吗?

4 个答案:

答案 0 :(得分:1)

您的代码示例有点混乱,因为两个结构看起来都是相同的。我假设他们在某些地方有所不同,其他人"。

首先,我建议创建一个围绕这些JSON反序列化的包装器。直接在JSON结构上工作是脆弱的。您的大部分程序都不应该意识到数据是以JSON形式出现的。因此,例如,您可以将其包含在包含Ads的{​​{1}}结构中,或者只是复制它所关心的部分。这样做也会使下面的一些更容易实现,而且不那么脆弱。

最常见的解决方案可能是创建一个界面:

AdsResponse

您使type Response interface { ID() int } Ads符合Others。然后您可以返回Response。如有必要,您可以稍后键入 - 切换以找出您拥有的那个并卸载其他数据。

Response

答案 1 :(得分:1)

我不明白你为什么把响应作为参数和作为回报。我想你不需要退货。您应该将指针传递给响应并用数据填充它。另外,我会返回一个错误而不是一个布尔值,但这是另一个主题。

无论如何,解决方案是使用interface {}(空接口)。

您很幸运,因为您使用的函数(FromJsonTo)接受一个空接口作为参数,因此您可以安全地将参数类型更改为接口{}并将其传递给FromJsonTo。像这样:

func Get(url string, response interface{}) bool {

    res, err := goreq.Request{
        Uri:         url,
    }.Do()

    // several validations

    res.Body.FromJsonTo(response)

    return true
}

警告:我没有编译代码。

然后你会用url和指向其中一个响应结构的指针调用这个函数:

var struct1 AdsResponse
var struct2 OtherResponse

Get("someURL", &struct1)
Get("someURL", &struct2)

答案 2 :(得分:0)

按照解决方案at Go Playground

进行操作

Go没有多态或任何其他类似OO的行为,因此,当您尝试将AdsResponse或OtherResponse结构作为Response(或任何接口{})传递时,这些值将成为Response(或指定的其他param类型),并且不可能去推断发起这些接口的真实类型{}并正确地将你的json解码为这些结构类型。

这种东西应该在OO语言中完美地运行,比如Java,C#等.Go中的结构/接口没有层次结构泛化/专门化。

您需要在Rest执行器或切换案例中执行类型断言,但似乎您需要一个通用的REST执行器,就像通用库一样。不合理地为程序中的每个结构创建一个switch case。也许你很快就会有数十个或数百个结构。

我认为一个合理的解决方案是其余的客户端传递一个lambda函数来为你做最后一步,就是创建一个正确的struct destination类型并调用json decode。

如上所述,我的示例中的executeRest()的返回类型将成为接口{},但是其余的客户端可以在executeRest()调用之后安全地执行返回值的类型断言。

答案 3 :(得分:0)

实现这一目标的方法是通过Go interfaces

两个选项:

空接口

CREATE TABLE
INSERT 0 1
ALTER TABLE
   Table "tmp.nocolumn"
 Column | Type | Modifiers 
--------+------+-----------

 count 
-------
     1
(1 row)

此选项允许为此功能赋予任何值。

自定义界面

创建自定义界面将允许您缩小可以作为函数参数提供的类型。

在这种情况下,您必须创建一个所有响应结构都需要遵守的接口。任何真正遵守该接口的结构都可以用作函数的参数。

这样的事情:

Get(url string, response interface{}) (Response, bool)

然后你的功能签名看起来像

type MyResponse interface {
    SomeFunction()
} 

只要Get(url string, response MyResponse) (MyResponse, bool) AdsResponse遵守OtherResponse接口,就可以将它们用作函数的参数。