Golang映射结构映射

时间:2018-08-15 01:57:42

标签: go

这是我的数据结构,正在尝试为此数据创建结构,但在错误内失败。

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

错误:-

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

代码:-

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)
}

阅读以下答案后,我尝试了此方法-

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)
}

最终输出:-

{{{test.jpg}}}

1 个答案:

答案 0 :(得分:0)

这里发生了许多容易混淆的问题。

输出:

首先要注意的是您没有指定任何特定的输出格式。 使用fmt.Println输出数据结构实际上只是为了方便调试,格式化是任意的,如果使用fmt.Printf("%#v\n", i),则可以在正确的Go中获得更可靠的格式化输出。默认的Println输出与Printf的“%v”等效。

要获取特定格式的输出(Go本身除外),则需要导入一个可以生成该格式的包。幸运的是,标准库中包含一些流行的格式。但是,在此之前,还有一些其他问题需要修复/理解。

导出:

结构的大写成员不导出,小写成员不导出。这意味着图像结构必须中的“ url”必须大写,否则诸如encoding/json之类的软件包将无法访问该成员以将其导出。

匿名类型:

其他人则强调为整体结构中的每种结构化数据类型创建明确的定义,我认为这通常是一个很好的建议。但是,如此多的一次性类型定义在周围浮动通常也是很愚蠢的,因此使用内联匿名结构定义在语言中是完全可以接受的。同样令人高兴的是,与定义的类型不同,结构相同的匿名类型被接受为同一类型。

这是一个使用匿名结构完成上述操作的例子,很病理。

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

虽然可行,但很混乱。但是请注意,您甚至可以将标签添加到匿名类型的字段中,以便json格式可以按预期转换。

另一种匿名处理并避免疯狂type定义的方法是使用地图。这是一个例子。但是请注意,如果某些Go货运人员看到您到处使用map[string]interface{},就会对您大喊大叫。尽管如此,实际上无论是在实践上还是在哲学上都没有错。

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

但是,通常来说,您想利用打字语言所能提供的优势。像Go这样的强类型语言非常擅长于尽早发现其他细微的错误。

这不是看起来更好吗?

type Object map[string]interface{}

// ...

j := Object{
    "data": Object{
        "image": Object{
            "url":"test.jpg",
        },
    },
}

再一次编码

这是您的程序更惯用的风格。在我看来,这并非巧合,也更具可读性。

    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))

    }

还请注意,虽然您必须导出成员以使它们出现在json中,但不必自己导出类型。