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 使用C#,asp.net读取Excel文件并保存到Oracle数据库
  • ¥15 C# datagridview 单元格显示进度及值
  • ¥15 thinkphp6配合social login单点登录问题
  • ¥15 HFSS 中的 H 场图与 MATLAB 中绘制的 B1 场 部分对应不上
  • ¥15 如何在scanpy上做差异基因和通路富集?
  • ¥20 关于#硬件工程#的问题,请各位专家解答!
  • ¥15 关于#matlab#的问题:期望的系统闭环传递函数为G(s)=wn^2/s^2+2¢wn+wn^2阻尼系数¢=0.707,使系统具有较小的超调量
  • ¥15 FLUENT如何实现在堆积颗粒的上表面加载高斯热源
  • ¥30 截图中的mathematics程序转换成matlab
  • ¥15 动力学代码报错,维度不匹配