首頁 > 後端開發 > Golang > 主體

IntTo Float64 JSON轉換之謎

WBOY
發布: 2024-09-03 13:20:19
原創
1135 人瀏覽過

The Mystery Of JSON Conversion Of IntTo Float64

使用 JSON 聽起來簡單明了,你有一些結構,你可以將其更改為 JSON - 一種通用的統一語言並返回到你的結構。簡單吧? ?

嗯,是的,但是直到你遇到 Marshal / Unmarshal 函數的一些奇怪行為。

問題 ?

這一切都始於我嘗試從 JWT 令牌讀取編碼的有效負載,以下是演示該問題的範例

package main

import (
    "encoding/json"
    "fmt"
)

type User struct {
    ID      int64   `json:"id"`
    PostIDs []int64 `json:"post_ids"`
}

func main() {
    u := User{
        ID:      1,
        PostIDs: []int64{1, 2, 3},
    }

    b, err := json.Marshal(u)
    if err != nil {
        panic(err)
    }

    m := make(map[string]interface{})
    if err = json.Unmarshal(b, &m); err != nil {
        panic(err)
    }

    userID, ok := m["id"].(int64)
    fmt.Printf("id: %d\nOk:%t\n", userID, ok)

    fmt.Println() // spliter

    postIDs, ok := m["id"].([]int64)
    fmt.Printf("post_ids: %v\nOk:%t\n", postIDs, ok)
}
登入後複製

只是編組和解組返回結構,因此預計會傳回相同的值!

不幸的是,這沒有發生,上面的程式碼輸出

// Result
id: 0
Ok:false

post_ids: []
Ok:false
登入後複製

當我看到這個輸出時,我?問題可能出在型別轉換上,所以我去檢查這些介面都有哪些類型

    fmt.Printf("id: %T\n", m["id"])
    fmt.Printf("post_ids: %T\n", m["post_ids"])
登入後複製
// Result
id: float64
post_ids: []interface {}
登入後複製

所以我們可以看到,JSON 將 int64 解析為 float64,這導致讀取資料時出現問題。

其實有兩種方法可以解決這個問題

?解決方案01(困難的方法)

使用float64的類型斷言,注意[]interface{}不能立即映射到[]float64,所以我們必須迭代每個元素並將其轉換

        // Parse UserID
    userID, _ := m["id"].(float64)
    fmt.Printf("id: %f\n", userID)

    fmt.Println() // spliter

    // Parse PostIDs
    postIDsArr, _ := m["post_ids"].([]interface{})
    postIDs := make([]int64, len(postIDsArr))
    for i, v := range postIDsArr {
        id, _ := v.(float64) // NOTICE: direct conversion to int64 won't work here!
        postIDs[i] = int64(id)
    }

    fmt.Printf("post_ids: %v\n", postIDs)
登入後複製
// Result
id: 1.000000

post_ids: [1 2 3]
登入後複製

?解決方案02(簡單方法)

將其解析回結構體

    b, err = json.Marshal(m) // m = map[string]interface{}
    if err != nil {
        panic(err)
    }

    var u2 User
    if err := json.Unmarshal(b, &u2); err != nil {
        panic(err)
    }

    fmt.Println(u2.ID)
    fmt.Println(u2.PostIDs)
登入後複製

當然,你可能會想,為什麼我們還要使用解決方案01,解決方案02不是更好嗎?

這取決於情況,您並不總是想創建一個結構體來從結構體中讀取單個屬性,所以正確的答案是——這取決於情況!

我想這就是今天的文章的全部內容,希望你學到一些新東西,我的地鼠夥伴? .

以上是IntTo Float64 JSON轉換之謎的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:dev.to
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板