doufen2769
2018-02-14 18:25
浏览 47
已采纳

将数组解组为struct

I'm trying to figure out how I can (using gin) create a struct from an api call

"icon": [
        "https://api.figo.me/assets/images/accounts/postbank.png",
        {
          "48x48": "https://api.figo.me/assets/images/accounts/postbank_48.png",
          "60x60": "https://api.figo.me/assets/images/accounts/postbank_60.png",
          "72x72": "https://api.figo.me/assets/images/accounts/postbank_72.png",
          "84x84": "https://api.figo.me/assets/images/accounts/postbank_84.png",
          "96x96": "https://api.figo.me/assets/images/accounts/postbank_96.png",
          "120x120": "https://api.figo.me/assets/images/accounts/postbank_120.png",
          "144x144": "https://api.figo.me/assets/images/accounts/postbank_144.png",
          "192x192": "https://api.figo.me/assets/images/accounts/postbank_192.png",
          "256x256": "https://api.figo.me/assets/images/accounts/postbank_256.png"
        }
      ],

into

type CatalogBank struct {
        Advice      string `json:"advice"`
        BankCode    string `json:"bank_code"`
        BankName    string `json:"bank_name"`
        BIC         string `json:"bic"`
        Credentials []struct {
            Label  string `json:"label"`
            Masked bool   `json:"masked"`
        } `json:"credentials"`
        Icon     []struct {

        } `json:"icon"`
        Language []byte `json:"language"`
    }

The icon part is just an extract from, but I always get an unmarshall error for this part. How would I have to definde the 'Icon' part in the struct?

图片转代码服务由CSDN问答提供 功能建议

我试图弄清楚如何(使用gin)通过api调用创建结构

 “ icon”:[
“ https://api.figo.me/assets/images/accounts/postbank.png",
 {
” 48x48“:”  https://api.figo.me/assets/images/accounts/postbank_48.png",
“ 60x60”:“ https://api.figo.me/assets/images/accounts/postbank_60.png”,\  n“ 72x72”:“ https://api.figo.me/assets/images/accounts/postbank_72.png",
” 84x84“:” https://api.figo.me/assets/images/accounts/  postbank_84.png“,
” 96x96“:” https://api.figo.me/assets/images/accounts/postbank_96.png",
“ 120x120”:“ https://api.figo.me/ 资产/图片/帐户/postbank_120.png",
“ 144x144”:“ https://api.figo.me/assets/images/accounts/postbank_144.png",
” 192x192“:” https://  api.figo.me/assets/images/accounts/postbank_192.png",
“ 256x256”:“ https://api.figo.me/assets/images/accounts/postbank_256.png"
} 
  ],
   
 
 

进入

  type CatalogBank结构{
建议字符串`json:“ advice”`\  n BankCode字符串`json:“ bank_code”`
 BankName字符串`json:“ bank_name”`
 BIC字符串`json:“ bic”`
凭据[] struct {
标签字符串`json:“ label”`  
 Masked bool`json:“ masked”`
}`json:“凭据”`
图标[] struct {
 
}`json:“ icon”`
语言[] byte`json:“ 语言”`
} 
   
 
 

图标部分仅是摘录的一部分,但我总是对此部分遇到编组错误。 我将如何在结构中定义“图标”部分?

  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

4条回答 默认 最新

  • douhezi2285 2018-02-14 18:30
    已采纳

    This would work

    package main
    
    type CatalogBank struct {
       Icon []interface{} `json:"icon"`
    }
    
    已采纳该答案
    打赏 评论
  • dqaq59269 2018-02-14 20:36

    This is a little tricky in Golang because of the non-strict type in the JSON. If that is definitely the format you are going to receive the data in, you should unmarshal to an Interface{} and then parse the interface into a struct that you can use in your Golang

    Direct Unmarshalling cannot be done, as the type of each field is not known

    type Icon struct{
        ImageLink string
        ImageLink48 string
        // ...
    }
    
    type CatalogBank struct {
        Advice      string `json:"advice"`
        IconRaw     []interface{} `json:"icon"`
        Icon        []Icon
        //...
    }
    
    func UnmarshalIcon(c &CatalogBank, i interface{}):
        // first convert it to the top level list
        newIcon := Icon{}
        listOfIcons := i.([]interface{})
        for _, i := range listOfIcons:
            switch iT := i.(type) {
               case string:
                    newIcon.ImageLink = iT
               case map[string]interface{}:
                  for smallIconsKey, smallIconLink := range iT {
                      if smallIconsKey == "48x48"{
                             newIcon.ImageLink48 = smallIconLink.(string)
                      }
                      // and so on
            }
    
    
    var c CatalogBank{}
    _ := json.Unmarshal([]byte(your_json), &c)
    for _, i := range c.IconRaw:
       UnmarshalIcon(&c, i)
    

    Caveat Emptor: I haven't checked above implementation but it should be something like this

    打赏 评论
  • dpa31905 2018-02-15 02:14

    You can not use []struct {} for icon, change it to []interface{} instead, or if you want operate on type safe type look at the second solution with cusom unmarshaler

    Solution 1

        package main
    
        import (
            "encoding/json"
            "fmt"
            "log"
        )
    
        type CatalogBank struct {
            Advice   string `json:"advice"`
            BankCode string `json:"bank_code"`
            BankName string `json:"bank_name"`
            BIC      string `json:"bic"`
            Credentials []struct {
                Label  string `json:"label"`
                Masked bool   `json:"masked"`
            } `json:"credentials"`
            Icon []interface{} `json:"icon"`
            Language []byte `json:"language"`
        }
    
        func main() {
    
            data := `
        {
        "Advice":"abc",
        "icon": [
                "https://api.figo.me/assets/images/accounts/postbank.png",
                {
                  "48x48": "https://api.figo.me/assets/images/accounts/postbank_48.png",
                  "60x60": "https://api.figo.me/assets/images/accounts/postbank_60.png",
                  "72x72": "https://api.figo.me/assets/images/accounts/postbank_72.png",
                  "84x84": "https://api.figo.me/assets/images/accounts/postbank_84.png",
                  "96x96": "https://api.figo.me/assets/images/accounts/postbank_96.png",
                  "120x120": "https://api.figo.me/assets/images/accounts/postbank_120.png",
                  "144x144": "https://api.figo.me/assets/images/accounts/postbank_144.png",
                  "192x192": "https://api.figo.me/assets/images/accounts/postbank_192.png",
                  "256x256": "https://api.figo.me/assets/images/accounts/postbank_256.png"
                }
              ]
        }
        `
    
            bank := &CatalogBank{}
    
            err := json.Unmarshal([]byte(data), bank)
            if err != nil {
                log.Fatal(err)
            }
            for _, icon := range bank.Icon {
                fmt.Printf(" %v
     ", icon)
            }
    
        }
    

    Solution 2:

        package main
    
        import (
            "encoding/json"
            "fmt"
            "log"
        )
    
        type Icons struct {
            URL    string
            BySize map[string]string
        }
    
    
    
        type CatalogBank struct {
            Advice   string `json:"advice"`
            BankCode string `json:"bank_code"`
            BankName string `json:"bank_name"`
            BIC      string `json:"bic"`
            Credentials []struct {
                Label  string `json:"label"`
                Masked bool   `json:"masked"`
            } `json:"credentials"`
            Icon     *Icons `json:"-,"`
            Language []byte `json:"language"`
        }
    
        func (p *CatalogBank) Unmarshal(data []byte) error {
    
    
            type Transient struct {
                *CatalogBank
                Icon []interface{} `json:"icon"`
            }
    
            var transient = &Transient{CatalogBank:p}
            err := json.Unmarshal([]byte(data), transient)
            if err != nil {
                return err
            }
            p.Icon = &Icons{
                BySize: make(map[string]string),
            }
    
            if len(transient.Icon) > 0 {
                if url, ok := transient.Icon[0].(string); ok {
                    p.Icon.URL = url
                }
                if aMap, ok := transient.Icon[1].(map[string]interface{}); ok {
                    for k, v := range aMap {
                        p.Icon.BySize[k] = v.(string)
                    }
                }
            }
            return nil
        }
    
        func main() {
    
            data := `
                {
                "Advice":"abc",
                "icon": [
                        "https://api.figo.me/assets/images/accounts/postbank.png",
                        {
                          "48x48": "https://api.figo.me/assets/images/accounts/postbank_48.png",
                          "60x60": "https://api.figo.me/assets/images/accounts/postbank_60.png",
                          "72x72": "https://api.figo.me/assets/images/accounts/postbank_72.png",
                          "84x84": "https://api.figo.me/assets/images/accounts/postbank_84.png",
                          "96x96": "https://api.figo.me/assets/images/accounts/postbank_96.png",
                          "120x120": "https://api.figo.me/assets/images/accounts/postbank_120.png",
                          "144x144": "https://api.figo.me/assets/images/accounts/postbank_144.png",
                          "192x192": "https://api.figo.me/assets/images/accounts/postbank_192.png",
                          "256x256": "https://api.figo.me/assets/images/accounts/postbank_256.png"
                        }
                      ]
                }
                `
    
            bank := &CatalogBank{}
            err := bank.Unmarshal([]byte(data))
            if err != nil {
                log.Fatal(err)
            }
            fmt.Printf("advice: %v
    ", bank.Advice)
    
            fmt.Printf("icon: %v
    ", bank.Icon.URL)
            for size, icon := range bank.Icon.BySize {
                fmt.Printf("%v =>  %v
     ",size, icon)
            }
        }
    

    打赏 评论
  • dongxiejie9387 2018-02-15 02:59

    You can define your icon like this:

    package main

    import (
        "fmt"
        "encoding/json"
    )
    
    var testIcon = []byte(`{"icon":[
                            "https://api.figo.me/assets/images/accounts/postbank.png",
                            {
                                "48x48":"https://api.figo.me/assets/images/accounts/postbank_48.png"
                            }]
                        }`)
    
    func main() {
    
        icon := make(map[string][]interface{})
        err := json.Unmarshal(testIcon, &icon)
        if err != nil {
            panic(err)
        }
    
        fmt.Println(icon)
        // map[icon:[https://api.figo.me/assets/images/accounts/postbank.png map[48x48:https://api.figo.me/assets/images/accounts/postbank_48.png]]]
    
    }
    
    打赏 评论

相关推荐 更多相似问题