我有这个简单的通用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()
接受不同的类型并返回相应的对象?
答案 0 :(得分:1)
假设DecodeJsonRequestBody
将第二个参数传递给json.Unmarshal或json.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)
不需要输入断言和类型转换。