【问题标题】:Golang mapping struct to mapGolang映射结构映射
【发布时间】:2018-08-30 12:02:26
【问题描述】:

这是我的数据结构,并试图为这些数据创建一个结构,但因错误而失败。

{
                "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}}}

【问题讨论】:

标签: go


【解决方案1】:

这里有许多容易混淆的问题。

输出:

首先,您没有指定任何特定的输出格式。 使用 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 定义疯狂的方法就是使用地图。这是那个例子。但是请注意,如果看到您在任何地方使用map[string]interface{},一些 Go 货物信徒会冲您大喊大叫。尽管如此,无论是在实践中还是在哲学上,它实际上都没有错。

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 中,但您不必自己导出类型。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-06-13
    • 1970-01-01
    • 1970-01-01
    • 2021-04-18
    • 1970-01-01
    • 1970-01-01
    • 2014-10-03
    • 1970-01-01
    相关资源
    最近更新 更多