Golang 映射结构映射

标签 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}}}

最佳答案

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

输出:

首先也是最重要的是您没有指定任何特定的输出格式。 使用 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 。这是那个例子。但请注意,如果一些 Go cargo 教徒看到您到处都在使用 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 中,但您不必导出类型本身。

关于Golang 映射结构映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51851938/

相关文章:

go - Golang中结构项字段的访问索引

go - Golang 中用于匹配传递的变量和类型的通用函数

go - AWS Cognito 刷新 token 在 secret 哈希上失败

google-app-engine - 在本地运行 Go App Engine 应用程序。

arrays - 戈朗 : Could not understand how below code is executing

Go - 如何组合多个错误对象

go - 为什么关闭sftp客户端不会关闭整个SSH连接

go - 在Golang中全局设置时区

string - 从 Go 中的 slice 中删除字符串

mysql - 无法使用 *DB.Rows() 获取所有行