这是我的数据结构,正在尝试为此数据创建结构,但在错误内失败。
{
"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}}}
答案 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中,但不必自己导出类型。