Hello all, I am trying to build a simple chat app to learn more about golang and am getting tripped up by json. When I try to decode I get no output and the "in" variable is empty. Here is my code so far for my client and server.
client:
func main() {
out := Message{name: "Jacob", text: "hey whats up"}
conn, err := net.Dial("tcp", "127.0.0.1:6666")
if err != nil {
panic(err)
}
err := json.NewEncoder(conn).Encode(&out)
if err != nil {
panic(err)
}
}
server:
func main() {
in := new(Message)
server, _ := net.Listen("tcp", "127.0.0.1:6666")
conn, _ := server.Accept()
err := json.NewDecoder(conn).Decode(&in)
if err != nil {
panic(err)
}
fmt.Println(in.name+":", in.text)
}
But when I run the two, my only output is ":". I know it has to be a dumb mistake, so any help or advice is appreciated!
评论:
Perelandric:
Eniac17:Go can't encode/decode private fields.
EDIT: Here's a working example with exported fields and field tags: https://play.golang.org/p/y-DmJ_iTPj
Killing_Spark:THANK YOU. Oh my I've been freaking out over this for two hours and forgot how go handled private fields. Oh the wonders of learning a new language
Perelandric:So your example works because you defined message explicitly as a type with those two fields?
Sorry if this question is dumb I just started reading up on go :)
Killing_Spark:No, the
Message
type was just left out of the question. It worked because I made the fields ofMessage
public, meaning they can be accessed by code outside of the package in which it was defined.Fields are made public by starting their name with a capital letter. So in the original code, it would have looked like this:
type Message struct { name string text string }
That defines a struct with two, private fields. Mine capitalizes those field names:
type Message struct { Name string Text string }
So now they're readable/writable by any code that gets a value of that type.
This is necessary because the
json
package (or more accurately, thereflect
package) can only work with fields that it can access.
danredux:Ah I see. Thanks for the thorough answer :)
code looks good but i think maybe you're using too many indirections? maybe?
in := new(Message) // in is now of type *Message Decode(&in) // now you're passing **Message
same goes for your encode..
