doucuo8618 2018-08-15 01:57
浏览 136
已采纳

Golang映射结构映射

Here is my data structure and trying to create a struct for this data but failing within error.

{
                "data": {
                  "image": {
                    "url": "tests.jpg"
                  }
                }
              }

Error:-

prog.go:16:20: invalid field name "Data" in struct initializer
prog.go:16:22: missing type in composite literal

Code:-

package main

import (
    "fmt"
)

type Images struct {
    Data struct {
        Image struct {
            url string
        }
    }
}

func main() {
    i := Images{"Data": {"Image": {"url": "test.jpg"}}}
    fmt.Println(i)
}

After reading the below answer, I tried this -

package main

import (
    "fmt"
)

//{ "data": {
//                  "image": {
//                    "url": "tests.jpg"
//                  }
//                }
//              }

type Images struct {
    Data Data
}
type Data struct {
    Image Image
}

type Image struct {
    url string
}

func main() {
    i := Images{
        Data: Data{
            Image: Image{url: "test.jpg"}}}
    fmt.Println(i)
}

Final output:-

{{{test.jpg}}}
  • 写回答

1条回答 默认 最新

  • duandang9434 2018-08-15 05:21
    关注

    There are a number of easy to conflate issues going on here.

    Output:

    First and foremost is you're not specifying any particular output formatting. Using fmt.Println to output data structures is really just for easy debugging, the formatting is pretty arbitrary you could get more reliably formatted output in correct Go if you used fmt.Printf("%#v ", i). The default Println outputs the equvelent of Printf's "%v".

    To get output in a particular format (other then Go itself) you'll need to import a package that can generate that format. Luckily a few popular formats are included in the standard library. But before we can get to that there are a few other things to fix / understand.

    Exports:

    Capitalized members of a struct are exported lower case members are not. This means that "url"in your image structure MUST be capitalized or else packages such as encoding/json will be unable to access the member to export it.

    Anonymous Types:

    Others emphasize creating explicit definitions for each of the structured data types in the overall structure, and I think that is generally good advice. However, it is also often silly to have so many one off type definitions floating around, so it is completely acceptable in the language to use inline anonymous structure definitions. Also a nice touch is that identically structured anonymous types are accepted as the same type unlike defined types.

    Here's an, admittedly pathological, example of doing the above with anonymous structs.

    i := struct{
        Data interface{} `json:"data"`
    }{
        Data:struct{
            Image interface{} `json:"image"`
        } {
            Image:struct{
                Url string `json:"url"`
            }{
                Url:"test.jpg",
            },
        },
    }
    

    While this works it's pretty messy. But notice you can even add tags to the fields of anonymous types so json formatting translates as intended.

    Another way to do it anonymously and avoid all this type definition crazy is just use a map. Here's that example. Note however, that some Go cargo cultists will yell at you if they see you using map[string]interface{} everywhere. Nevertheless there's actually nothing wrong with it either in practice or in philosophy.

    j := map[string]interface{} {
        "data":map[string]interface{}{
            "image":map[string]interface{}{
                "url":"test.jpg",
            },
        },
    }
    

    Generally however, you want to take advantage of what a typed language can give you. Strongly typed languages like Go are very good at finding otherwise subtile bugs early on.

    And isn't this better looking:

    type Object map[string]interface{}
    
    // ...
    
    j := Object{
        "data": Object{
            "image": Object{
                "url":"test.jpg",
            },
        },
    }
    

    Once More With Encoding

    Here's your program in a more idiomatic style. Which, not coincidentally, is also more readable in my opinion.

        package main
    
        import (
            "fmt"
            "encoding/json"
        )
    
        type data struct {
            Image image `json:"image"`
        }
    
        type image struct {
            Url string `json:"url"`
        }
    
        type images struct {
            Data data `json:"data"`
        }
    
    
        func main() {
            i := images{Data: data{Image: image{Url: "test.jpg"}}}
    
            data, _ := json.Marshal(i)
            fmt.Println(string(data))
    
        }
    

    Also note that while you must export the members to have them appear in the json, you do not have to export the types themselves.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何让企业微信机器人实现消息汇总整合
  • ¥50 关于#ui#的问题:做yolov8的ui界面出现的问题
  • ¥15 如何用Python爬取各高校教师公开的教育和工作经历
  • ¥15 TLE9879QXA40 电机驱动
  • ¥20 对于工程问题的非线性数学模型进行线性化
  • ¥15 Mirare PLUS 进行密钥认证?(详解)
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥20 想用ollama做一个自己的AI数据库
  • ¥15 关于qualoth编辑及缝合服装领子的问题解决方案探寻
  • ¥15 请问怎么才能复现这样的图呀