Golang конвертирует значение json из int в строку

Я получаю ответ json. Который имеет ключ pk и его значение как int. Мне нужно преобразовать его в строку, как проще всего? Вот пример

"pk": 145250410

и мне нужно, чтобы это было

"pk": "145250410"

Я не могу сделать модель и разобрать ее, потому что я не всегда знаю, каким будет мой json, но я знаю, что у него всегда будет pk, поэтому я его анализирую.

var bdoc interface{}
bson.UnmarshalJSON([]byte(gjson.Get(*str, "user").String()), &bdoc)

Единственная проблема в том, что я получаю pk как int, а не как строку.


person Miljan Rakita    schedule 27.04.2018    source источник
comment
strconv.FormatInt? Или вы пытаетесь маршалировать или демаршалировать напрямую как строку?   -  person JimB    schedule 27.04.2018
comment
@JimB Весь мой json находится в *str. Я распаковываю json и получаю интерфейс map[string]{}.   -  person Miljan Rakita    schedule 27.04.2018
comment
Непонятно, что вы спрашиваете. Создайте минимально воспроизводимый пример.   -  person JimB    schedule 27.04.2018
comment
У вас есть строки в вашем json, например 0000012345?   -  person Slabgorb    schedule 27.04.2018
comment
@Slabgorb Может быть так   -  person Miljan Rakita    schedule 27.04.2018


Ответы (1)


package main

import (
    "encoding/json"

    "fmt"
    "strconv"
)

var jsonData = []byte(`
{
    "user": {
        "media_count": 2043,
        "follower_count": 663,
        "following_count": 1300,
        "geo_media_count": 0,
        "is_business": false,
        "usertags_count": 423,
        "has_chaining": true,
        "is_favorite": false,
        "has_highlight_reels": true,
        "include_direct_blacklist_status": true,
        "pk": 145250410,
        "username": "karahray",
        "full_name": "K Ray \ud83d\udd35",
        "has_anonymous_profile_picture": false,
        "is_private": false,
        "is_verified": false,
        "profile_pic_url": "",
        "profile_pic_id": "1403809308517206571_145250410",
        "biography": "Austinite, oncology dietitian, lover of food, coffee, beer, scenic jogs, traveling, Los Spurs, my Yorkies and LAUGHING! Fitness/food @LGFTatx!",
        "external_url": "",
        "hd_profile_pic_url_info": {
            "height": 1080,
            "url": "",
            "width": 1080
        },
        "hd_profile_pic_versions": [{
            "height": 320,
            "url": "",
            "width": 320
        }, {
            "height": 640,
            "url": "",
            "width": 640
        }], 
        "reel_auto_archive": "on",
        "school": null,
        "has_unseen_besties_media": false,
        "auto_expand_chaining": false
    },
    "status": "ok"
}`)


// custom json unmarshal
type pk string

func (p *pk) UnmarshalJSON(data []byte) error {
    var tmp int
    if err := json.Unmarshal(data, &tmp); err != nil {
        return err
    }
    *p = pk(strconv.Itoa(tmp))
    return nil
}

type jsonModel struct {
    User struct {
        PK pk `json:"pk"`
    } `json:"user"`
}

func main() {
    // using the custom json unmarshal
    jm := &jsonModel{}
    if err := json.Unmarshal(jsonData, jm); err != nil {
        panic(err)
    }

    // doing it as map[string]interface, then finding the key, 
    // then converting - you end up needing TONS of casting 
    everything := map[string]interface{}{}
    if err := json.Unmarshal(jsonData, &everything); err != nil {
        panic(err)
    }

    var userPart interface{}
    userPart, ok := everything["user"]
    if !ok {
        panic("could not find user key")
    }
    userPartMap := userPart.(map[string]interface{})
    var pkInterface interface{}

    if pkInterface, ok = userPartMap["pk"]; !ok {
        panic("could not find pk key")
    }

    // note that json is going to 'guess' float64 here, so we 
    // need to do a lot of shenanigans.
    pkString := strconv.FormatInt(int64(pkInterface.(float64)),10)

    fmt.Printf("%s\n", jm.User.PK)
    fmt.Printf("%s\n", pkString)


}

Выход:

145250410

145250410

https://play.golang.org/p/OfHi0ybHJXE

person Slabgorb    schedule 27.04.2018
comment
Я не знаю, каким будет ответ, поэтому я не использую структуру... Это основная проблема. - person Miljan Rakita; 27.04.2018
comment
Пока ключ «pk» находится на верхнем уровне json, это будет работать независимо от оставшейся структуры json. Другими словами, вам не нужно разбирать ВСЕ сразу, вы можете разбирать только то, что ищете. - person Slabgorb; 27.04.2018
comment
я надеюсь, что это поможет вам, мой json выглядит так: pastebin.com/JgM347zP здесь вы можете увидеть этот pk имеет тип int, и мне нужно преобразовать его в строку типа. Это то, чего я пытаюсь достичь - person Miljan Rakita; 27.04.2018
comment
это всегда будет иметь только pk. Если я попробую этот fmt.Printf(%s, p.PK), вывод будет следующим: {000012345} И остальной части json нет. - person Miljan Rakita; 27.04.2018
comment
Хорошо, отредактированный ответ, включая ваш json. Вероятно, кто-то другой мог бы придумать более эффективный способ работы с неструктурированной версией. Я пытался избежать таких вещей, как использование отражения. Я бы по-прежнему рекомендовал не запускать map[string]interface{} через вашу программу, это только усложняет задачу. Одна вещь, которую можно значительно улучшить, — это использование приведения с двумя возвратами, чтобы предотвратить случайную панику из-за плохого приведения. - person Slabgorb; 28.04.2018