Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

encoding/json: Field name tag not respected when encoding if there is a space after ":" #14142

Closed
arcrose opened this issue Jan 28, 2016 · 3 comments

Comments

@arcrose
Copy link

arcrose commented Jan 28, 2016

I've found that, when encoding a struct into JSON, if there is a space after the colon character in the tag for the field in the struct in question, then the field will not be renamed. Below is some very simple code demonstrating what I mean.

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json: "name"`
    Age  int    `json: "age"`
}

func main() {
    p := Person{"Alice", 29}
    bytes, _ := json.Marshal(p)
    fmt.Println(string(bytes))
}

As you can see, in the above code I've made the apparent "mistake" of adding a space in my JSON tags.
If I run this code, the output I get the following output.

{"Name":"Alice","Age":29}

Now if I change the struct definition to the following

type Person struct {
    Name string `json:"name"`
    Age  int    `json:"age"`
}

and then recompile and run the code, I get the expected output

{"name":"Alice","age":29}

What's interesting is that this isn't a problem when decoding JSON. Reintroducing spaces after the colon character, and switching to decoding from bytes, you'll see that the struct is populated properly even though I have switched the order of the fields in the JSON. I take this to mean that the decoder understands the JSON tags even with the space when decoding.

package main

import (
    "encoding/json"
    "fmt"
)

type Person struct {
    Name string `json: "name"`
    Age  int    `json: "age"`
}

func main() {
    data := []byte(`{"age": 29, "name": "Alice"}`)
    p := Person{}
    json.Unmarshal(data, &p)
    fmt.Println(p)
}

The output I get is, as expected,

{Alice 29}

I should note that I've also experimented with using a Decoder and Encoder instead of Unmarshal and Marshal. They suffer from the same problem (and I assume share a similar implementation to their respective counterparts).

I tested this running Go 1.5.3 on the latest OS X. The output of go version is

go version go1.5.3 darwin/amd64

It seems to me that the encoding/json's decoding and encoding functionality should behave the same with regards to how struct tags are treated. I should be able to have spaces after ":" in the tag and still have struct fields encoded such that the right keys are used, especially since decoding isn't affected by this.

@ianlancetaylor
Copy link
Contributor

It's working on decode because, in the absence of a tag or an exact match, Decode does a case-insensitive match of tag name to field name.

We want field tag parsing to be a simple as possible: no whitespace or any other syntax beyond what is specified. This is working as intended.

@arcrose
Copy link
Author

arcrose commented Jan 29, 2016

@ianlancetaylor Just because it's "intended" to work that way doesn't mean it's good.
This behavior is misleading and confusing. There is no indication, such as a compile-time warning, about the behavior, and it's quite confusing. It necessitates an understanding of a very particular and frankly unusual piece of trivia about the Go compiler, and I think it's not in the language's interest to leave something so vague.
I'm not sure I understand why, in a language whose formatting tools encourage some superfluous whitespace between things like struct field names and their types, a little extra checking can't be done to avoid subtle cases like this.
Can this not be a discussion that isn't just shut down because of what your sacred spec says?

@ianlancetaylor
Copy link
Contributor

Yes, this can be a discussion, but the discussion should not take place on the bug tracker. It's not a bug: the code is working as documented and the documentation seems reasonably clear. For discussions, please see https://golang.org/wiki/Questions . Thanks.

@golang golang locked and limited conversation to collaborators Feb 3, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants