簡體   English   中英

Golang json解碼無法解碼接口{}

[英]Golang json decoding fails to decode interface{}

我正在使用一個庫(go-kit),它要求我指定函數來編碼/解碼我的請求和響應類型到/從JSON。 對於編碼,它很簡單:

func EncodeResponse(_ context.Context, w http.ResponseWriter, response interface{}) error {
    return json.NewEncoder(w).Encode(response)
}

我傳遞此函數來創建HTTP服務器,它工作正常。 但是,他們提出的請求方法是將表單單獨起作用:

func decodeUppercaseRequest(_ context.Context, r *http.Request) (interface{}, error) {
    var req UppercaseRequest
    if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
        return nil, err
    }
    return req, nil
}

對於我的應用程序中的每個RPC。 我真的想保持我的代碼DRY並避免使用數百種幾乎相同的方法。 因此,我嘗試編寫一個函數來生成解碼給定請求類型的閉包:

func DecodeRequest(req interface{}) httptransport.DecodeRequestFunc {
    return func(_ context.Context, r *http.Request) (interface{}, error) {
        if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
            return nil, err
        }
        return req, nil
    }
}

可以像這樣調用此函數:

DecodeRequest(UppercaseRequest{}}

不幸的是,當我這樣做時,JSON解碼失敗,即使req的類型實際上是mypackage.UppercaseRequest。 我不知道從哪里開始。 有沒有辦法可以避免每個請求類型編寫一個方法? 有什么方法可以幫助Decode函數了解這種類型在運行時是什么? 提前致謝!

這是一個展示問題的游樂場: https//play.golang.org/p/GgHsLffp1G

根據您向我們展示的那段代碼,我認為您正面臨類型斷言問題。 我創建了一個游樂場,向您展示我在下面解釋的內容

您正在將UpperCaseRequest傳遞給DecodeRequest func。 在這個函數中,參數是interface {}類型,它將此參數的指針傳遞給json Decoder。 因此,解碼器看到一個指向接口的指針,而不是指向UpperCaseRequest的指針。

這就是為什么它沒有被正確解碼。 然后,嘗試對其進行類型斷言失敗,因為斷言兩種不同的類型是不可能的。

所以,在你的代碼中,我建議:

func DecodeRequest(req interface{}) httptransport.DecodeRequestFunc {
    return func(_ context.Context, r *http.Request) (interface{}, error) {
        // Note the '&' is removed here
        if err := json.NewDecoder(r.Body).Decode(req); err != nil {
            return nil, err
        }
        return req, nil
    }
}

並調用此函數:

// Note the & is placed here.
DecodeRequest(&UppercaseRequest{}}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM