第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Golang Interface{} 不會將斷言輸入到 int

Golang Interface{} 不會將斷言輸入到 int

Go
呼喚遠(yuǎn)方 2022-10-10 18:00:07
我正在開發(fā)一個rest api,但由于某種原因無法將接口{} 鍵入到它的底層類型 - int。我通過發(fā)布請求發(fā)送數(shù)據(jù),以創(chuàng)建廣告。它看起來像這樣:POST http://localhost:8080/api/ads    {        "Title": "Example Title",        "Section": "machinery",        "CostPerDayInCent": 34500,        "Description": "A description",        "User": 4,        "AllowMobileContact": true,        "AllowEmailContact": true,        "IsActive": false    }傳遞的值被解碼為 map[string]interface{},如下所示:var adToValidate map[string]interface{}err = json.NewDecoder(r.Body).Decode(&adToValidate)    if err != nil {        api.errorLog.Printf("Error decoding ad object: %v", err)        http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)        return    }當(dāng)我鍵入將 costperdayincent 和用戶界面值斷言為 int 時,我的問題發(fā)生了。localScopeAd.CostPerDayInCent, ok = adMapToValidate[“CostPerDayInCent”].(int)if !ok {    fieldErrors[structFieldName] = fmt.Sprintf("%v value is not of int type", structFieldName)}if 語句執(zhí)行,表明它不能鍵入 assert。為什么是這樣?是不是因為傳遞的 json 將每個值都視為字符串?我將如何解決這個問題?跟進(jìn)我在@DanielFarrell 的回答的幫助下解決了這個問題。由于我無法在評論部分做出回應(yīng),以下是我解碼為地圖而不是結(jié)構(gòu)的原因:我知道解碼成結(jié)構(gòu)會更有意義。我最初是在解碼成一個結(jié)構(gòu)。但是,我在嘗試驗證布爾值時遇到了一些問題。即“AllowMobileContact”:真,“AllowEmailContact”:真,“IsActive”:假如果用戶要發(fā)出發(fā)布請求以創(chuàng)建廣告而忽略上述值。當(dāng)請求正文被解碼時,上述字段在結(jié)構(gòu)中將默認(rèn)為 false(布爾值 0)。如果我要驗證傳入的值,我將不知道用戶是否輸入了 false 或遺漏了整個鍵值對。因為我想確保用戶輸入了這些值,所以我首先將其解碼為一個映射,以便我可以檢查 bool 鍵值對的鍵是否存在。然后,如果缺少一些必需的布爾數(shù)據(jù),我可以發(fā)送相關(guān)響應(yīng)。如果您知道上述內(nèi)容的更簡單方法,我將有興趣聽到它。有一些 3rd 方包有 3 種布爾值類型,它們可能有效,但我決定改用上面的。
查看完整描述

1 回答

?
PIPIONE

TA貢獻(xiàn)1829條經(jīng)驗 獲得超9個贊

我更愿意解碼成一個結(jié)構(gòu)并讓json/encoding處理正確類型的工作。


type Input struct {

    Title,

    Selection string

    CostPerDayInCent int64

    Description      string

    User             int64

    AllowMobileContact,

    AllowEmailContact,

    IsActive bool

}

由于幾個原因,這種方法非常普遍和有用。首先,您可以選擇類型。其次,您正在定義一個類型,因此您可以附加函數(shù),我發(fā)現(xiàn)它作為一種組織代碼并避免將結(jié)構(gòu)作為顯式函數(shù)參數(shù)傳遞的方法非常方便。第三,您可以將注釋附加到結(jié)構(gòu)的字段,進(jìn)一步調(diào)整解組。


最后,對我來說,最重要的是,您正在以 Go 處理數(shù)據(jù)的方式思考數(shù)據(jù)。在許多流行的現(xiàn)代語言(如 Python)中,代碼和文檔通常不會將類型附加到函數(shù),或嘗試顯式枚舉對象的屬性。圍棋不一樣。它消除了固有的語言反射是它如此高效的原因之一。這可以為程序員提供巨大的好處——當(dāng)您了解所有類型時,您就可以確切地知道事物的行為方式,并且可以準(zhǔn)確地確定必須傳遞您調(diào)用的函數(shù)的內(nèi)容。我建議您接受顯式類型,并盡可能避免將 json 解碼為面向接口的類型。你會知道你在處理什么,你也可以為你的消費者明確地定義它。


https://play.golang.org/p/egaequIT8ET與您的方法形成鮮明對比,您無需費心定義類型 - 但您也沒有機會選擇它們。


package main


import (

    "bytes"

    "encoding/json"

    "fmt"

)


type Input struct {

    Title,

    Selection string

    CostPerDayInCent int64

    Description      string

    User             int64

    AllowMobileContact,

    AllowEmailContact,

    IsActive bool

}


func main() {

    var input = `{

        "Title": "Example Title",

        "Section": "machinery",

        "CostPerDayInCent": 34500,

        "Description": "A description",

        "User": 4,

        "AllowMobileContact": true,

        "AllowEmailContact": true,

        "IsActive": false

    }`

    // map[string]interface

    data := make(map[string]interface{})

    if err := json.NewDecoder(bytes.NewBufferString(input)).Decode(&data); err != nil {

        panic(err)

    }


    fmt.Printf("%f %T\n", data["CostPerDayInCent"], data["CostPerDayInCent"])


    // structure

    obj := new(Input)

    if err := json.NewDecoder(bytes.NewBufferString(input)).Decode(obj); err != nil {

        panic(err)

    }

    fmt.Printf("%d %T", obj.CostPerDayInCent, obj.CostPerDayInCent)

}


查看完整回答
反對 回復(fù) 2022-10-10
  • 1 回答
  • 0 關(guān)注
  • 157 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號