"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > IntTo Float64의 JSON 변환 미스터리

IntTo Float64의 JSON 변환 미스터리

2024-11-02에 게시됨
검색:286

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가 더 좋지 않느냐고 생각할 수도 있습니다.

물론 상황에 따라 다릅니다. 구조체에서 단일 속성을 읽기 위해 항상 구조체를 생성하고 싶지는 않으므로 정답은 -- 상황에 따라 다릅니다!

오늘 기사는 여기까지인 것 같습니다. 새로운 것을 배웠으면 좋겠습니다. 고퍼 여러분?.

릴리스 선언문 이 기사는 https://dev.to/aehelaly/the-mystery-of-json-conversion-of-int64-to-float64-5eof?1에 복제되어 있습니다. 침해가 있는 경우에는 [email protected]으로 문의하시기 바랍니다. 그것을 삭제하려면
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3