如何使功能适用于不同的输入类型?

时间:2017-03-02 06:10:08

标签: go struct

我有这个简单的通用Request结构来在我的应用程序中发出get请求:

package api

import (
    "net/http"
    "time"
    "log"
    "app/errors"
)

type Request struct {
    Url string
}

func (request *Request) Run(responseObject *AppStatusInfo) *errors.Error {

    req, requestErr := http.NewRequest(http.MethodGet, request.Url, nil)

    req.Header.Set("Content-Type", "application/json")

    timeout := time.Duration(5 * time.Second)

    client := &http.Client{
        Timeout: timeout,
    }

    resp, requestErr := client.Do(req)

    if requestErr != nil {
        return &errors.UnknownError
    }

    decodeError := DecodeJsonRequestBody(resp, &responseObject)

    if (decodeError != nil) {
        return &errors.UnknownError
    }

    defer resp.Body.Close()

    return nil
}

此处responseObject具有AppStatusInfo类型的指针,它是具有一些字段的结构。

我像这样运行以获取应用状态信息并将其放在appStatusInfo对象中:

var appStatusInfo AppStatusInfo

req := Request{
    Url:config.Config.ApiUrl,
}

req.Run(&appStatusInfo)

所以,这段代码运行正常。

但是,当我想概括请求接受其他类型的回复时,例如UserProducts,我不知道如何在不将responseObject *AppStatusInfo替换为responseObject interface{}的情况下执行此操作,然后使用responseObject。(UserProducts)来构建它,我认为可以改进它。

因此,只要没有泛型,我如何让Request.Run()接受不同的类型并返回相应的对象?

1 个答案:

答案 0 :(得分:1)

假设DecodeJsonRequestBody将第二个参数传递给json.Unmarshaljson.Decoder.Decode,那么就这样写。我只显示更改的行:

func (request *Request) Run(responseObject interface{}) *errors.Error {
   ...
   resp, requestErr := client.Do(req)
   if requestErr != nil {
      return &errors.UnknownError
   }
   defer resp.Body.Close()   // defer close before doing anything else
  ...
  decodeError := DecodeJsonRequestBody(resp, responseObject) // don't take address of responseObject
  ...
}

您可以这样称呼它:

var up UserProducts
err = r.Run(&up)

var asi AppStatusInfo
err = r.Run(&asi)

不需要输入断言和类型转换。