douhu3424 2017-03-02 06:10
浏览 45
已采纳

如何使函数适用于不同的输入类型?

I have this simple generic Request struct to make get requests in my app:

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
}

Here responseObject has pointer of type AppStatusInfo which is a struct with some fields.

I run it like this to get app status information and put it inside appStatusInfo object:

var appStatusInfo AppStatusInfo

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

req.Run(&appStatusInfo)

So, this code runs fine.

But, when I want to generalize Request to accept other types of responses, like UserProducts, I don't know how to do it without replacing responseObject *AppStatusInfo with responseObject interface{}, then casting it with responseObject.(UserProducts) which I think can be improved.

So, as soon as there are no generics, how do I make Request.Run() accept different types and return respective objects?

  • 写回答

1条回答 默认 最新

  • doufu5401 2017-03-02 07:00
    关注

    Assuming that DecodeJsonRequestBody passes the second argument to json.Unmarshal or json.Decoder.Decode, then write it like this. I show the changed lines only:

    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
      ...
    }
    

    You can call it like this:

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

    Type assertions and type conversions are not required.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端
  • ¥15 基于PLC的三轴机械手程序