1 回答
TA贡献1875条经验 获得超3个赞
这里有许多容易混淆的问题。
输出:
首先也是最重要的是您没有指定任何特定的输出格式。使用 fmt.Println 输出数据结构实际上只是为了方便调试,格式非常随意,如果使用fmt.Printf("%#v\n", i). 默认的 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 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 中,但您不必自己导出类型。
- 1 回答
- 0 关注
- 116 浏览
添加回答
举报