2017-03-02 14 views
0

私は私のアプリでリクエストを取得するには、このシンプルな汎用的なリクエスト構造体を持っている:さまざまな入力タイプで機能を動作させる方法は?

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でそれをキャスト、responseObject interface{}responseObject *AppStatusInfoを交換することなく、どのように行うのか分からない。(UserProducts)私ができると思います改善する。

したがって、ジェネリックスがないとすぐに、Request.Run()に異なるタイプを受け入れてそれぞれのオブジェクトを返すようにしますか?

+0

空のインターフェイスが唯一のオプションであることを確かめてください。 –

答えて

1

DecodeJsonRequestBodyjson.Unmarshalまたはjson.Decoder.Decodeに2番目の引数を渡したとすると、次のように記述します。私は、変更線を表示:

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) 

タイプのアサーションと型変換が必要とされていません。

関連する問題