英文:
Go - Encode nested structure
问题
我正在修改http://gary.burd.info/go-websocket-chat的扩展。
这个示例通过Websockets发送原始文本。
我想要使用JSON数据。
我在Go代码中定义了一些结构,但是当我将其转换为JSON并写入客户端时,嵌套的结构不在结果中。
一些代码:
type ChatroomData struct {
Token string `json:"token"`
Chatroom *Chatroom `json:"chatroom"`
}
type Message struct {
Token string `json:"token,omitempty"`
Type string `json:"type"`
Author string `json:"author"`
Content string `json:"content"`
Chatroom string `json:"chatroom"`
}
type Messages []Message
聊天室结构:
type Chatroom struct {
Name string `json:"name"`
Users []User `json:"users"`
Messages Messages `json:"messages"`
Hub *WsHub `json:"-"`
}
type Chatrooms map[string]*Chatroom
type User struct {
Username string `json:"username"`
Token string `json:"-"`
}
type Users []User
启动聊天室:
func (s *Server) startMainChatroom() {
s.Chatrooms["main"] = &Chatroom{
Name: "main",
Users: make([]User, 0),
Messages: make([]Message, 0),
Hub: NewHub(),
}
go s.Chatrooms["main"].Hub.Run()
}
将消息添加到聊天室的方法:
message := Message{}
json.Unmarshal([]byte(data), &message)
message.Token = ""
message.Type = "message"
chatroom.Messages = append(chatroom.Messages, message)
向客户端发送数据:
func (u *User) SendChatroomData(w http.ResponseWriter, c *Chatroom, status int) {
chatroomData := ChatroomData{Token: u.Token, Chatroom: c}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "accept, authorization")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(&chatroomData); err != nil {
panic(err)
}
}
打印的结果是:
{
"token": "a638ed3ba0c30ba3d0810fc79e12a50a",
"chatroom": {
"name": "main",
"users": [{}, {}],
"messages": []
}
}
有两个用户和三条消息被发送。如果我使用fmt.Printf("%v\n", chatroom.Messages)
,我可以正确地获取这三条消息。对于用户也是一样,数据在转储时是存在的。
有很多奇怪的地方:
- 为什么
messages
键保持为空? - 为什么
users
键不为空,但切片项为空?(由Mike Reedell解决)
谢谢你的帮助,如果需要,可以继续询问更多的代码。希望我的帖子还不算太长(也不要有太多的英语错误X))!
英文:
I'm working on an extension of http://gary.burd.info/go-websocket-chat.
This example sends raw text through websockets.
I want to use JSON data instead.
I did some structures in my Go code, but when I convert it to JSON to write it to the client, the nested structures are not in the result.
Some code :
type(
ChatroomData struct {
Token string `json:"token"`
Chatroom *Chatroom `json:"chatroom"`
}
Message struct {
Token string `json:"token,omitempty"`
Type string `json:"type"`
Author string `json:"author"`
Content string `json:"content"`
Chatroom string `json:"chatroom"`
}
Messages []Message
)
The chatroom struct :
Chatroom struct {
Name string `json:"name"`
Users []User `json:"users"`
Messages Messages `json:"messages"`
Hub *WsHub `json:"-"`
}
Chatrooms map[string]*Chatroom
User struct {
username string `json:"username"`
token string `json:"-"`
}
Users []User
Start the chatroom :
func (s *Server) startMainChatroom() {
s.Chatrooms["main"] = &Chatroom{
Name: "main",
Users: make([]User, 0),
Messages: make([]Message, 0),
Hub: NewHub(),
}
go s.Chatrooms["main"].Hub.Run()
}
The way to append messages to the chatroom :
message := Message{}
json.Unmarshal([]byte(data), &message)
message.Token = ""
message.Type = "message"
chatroom.Messages = append(chatroom.Messages, message)
Send data to the client :
func (u *User) SendChatroomData(w http.ResponseWriter, c *Chatroom, status int) {
chatroomData := ChatroomData{Token: u.token, Chatroom: c}
w.Header().Set("Access-Control-Allow-Origin", "*")
w.Header().Set("Access-Control-Allow-Headers", "accept, authorization")
w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
w.WriteHeader(status)
if err := json.NewEncoder(w).Encode(&chatroomData); err != nil {
panic(err)
}
}
The printed result is :
{
"token":"a638ed3ba0c30ba3d0810fc79e12a50a",
"chatroom":{
"name":"main",
"users":[{},{}],
"messages":[]
}
}
There are two users and three messages were sent. If I use fmt.Printf("%v\n", chatroom.Messages)
, I have the three messages correctly stored. Same for the users, data is here when I dump it.
Many things are strange :
- Why the
messages
key stays empty ? - Why the
users
key doesn't, but the slice items are empty ? (solved by Mike Reedell)
Thank you for your help, don't hesitate to ask me more code if it needs to be. I hope my post isn't already too long (and not too full of english errors X)) !
答案1
得分: 1
go的JSON编组器只会输出导出的(大写字母开头)字段。User
结构体中的字段是未导出的(小写字母开头),这意味着JSON编组器不知道它们的存在,无法输出它们。
英文:
The go JSON marshaler will only output exported (capitalized) fields. The field in the User
struct are un-exported (lower-case), which means the JSON marshaler doesn't know they are there and can't output them.
答案2
得分: 0
问题完全出在其他地方:当我添加一些消息时,我使用的Chatroom实例没有正确绑定到s.Chatrooms["main"]
,这是因为我对指针的误解。
当我编排s.Chatrooms["main"]
时,消息并不在其中!
感谢你的帮助!
希望这对其他Go学习者有所帮助:D
英文:
The problem was totally elsewhere : The Chatroom instance I used when adding some messages wasn't bound correctly to s.Chatrooms["main"]
, due to my misunderstanding of pointers.
When I marshaled s.Chatrooms["main"]
, the messages weren't inside !
Ty for your help !
I hope this will help some others go-learners
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论