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: struct tags to ignore fields don't work on unexported fields #4660

Closed
bradfitz opened this issue Jan 15, 2013 · 7 comments

Comments

Projects
None yet
4 participants
@bradfitz
Copy link
Member

commented Jan 15, 2013

The json annotations to both ignore and rename fields don't work for unexported fields.


Example:


package main

import (
        "encoding/json"
        "log"
)

type T struct {
        Name string
        m    map[string]interface{} `json:"-"`
        m2   map[string]interface{} `json:"sldkjfsd"`
}

func main() {
        input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}}`
        t := &T{}
        err := json.Unmarshal([]byte(input), t)
        log.Printf("Name %q; err: %v", t.Name, err)
}

Generates:

2013/01/14 17:17:11 Name "Bob"; err: json: cannot unmarshal object key
"m" into unexported field m of type main.T

Interestingly, the first case "m" works with Go 1.0.3 and only fails with tip.

But "m2" fails with both 1.0.3 and tip.
@rsc

This comment has been minimized.

Copy link
Contributor

commented Jan 15, 2013

Comment 1:

I am inclined to say that the Go 1.0.3 behavior is correct and that the only regression
here is the `json:"-"` being incorrectly ignored at tip.
One could argue for ignoring the unexported fields entirely, but then people ask why
Unmarshal is silently doing nothing. I think the error does help most people.

Labels changed: added priority-later, removed priority-triage.

@bradfitz

This comment has been minimized.

Copy link
Member Author

commented Jan 15, 2013

Comment 2:

That's a bit unfortunate, in that you can then never safely unmarshal into a struct
containing unexported fields if you can't be certain the input will never contain those
field names in the future.
I just had a split a type into two because of this.
Oh well.  At least this works:
type TInner struct {
        Name string
}
type T struct {
        TInner
        m    map[string]interface{}
        m2   map[string]interface{}
}
func main() {
        input := `{"Name": "Bob", "m": {"x": 123}, "m2": {"y": 456}}`
        var t T
        err := json.Unmarshal([]byte(input), &t.TInner)
        log.Printf("Name %q; err: %v", t.Name, err)
}
@gopherbot

This comment has been minimized.

Copy link

commented Jan 17, 2013

Comment 3 by rickarnoldjr:

Fixed by https://golang.org/cl/7139049/
@adg

This comment has been minimized.

Copy link
Contributor

commented Jan 17, 2013

Comment 4:

Thanks Rick, but it's not fixed until the fix is submitted. :-)

Status changed to Started.

@adg

This comment has been minimized.

Copy link
Contributor

commented Jan 17, 2013

Comment 5:

I am inclined to agree with Brad. I think encoding/json should behave as if unexported
fields do not exist.
@rsc

This comment has been minimized.

Copy link
Contributor

commented Jan 17, 2013

Comment 6:

Okay, let's try it.
@rsc

This comment has been minimized.

Copy link
Contributor

commented Jan 22, 2013

Comment 7:

This issue was closed by revision 6e3f3af.

Status changed to Fixed.

@bradfitz bradfitz added fixed labels Jan 22, 2013

@rsc rsc added this to the Go1.1 milestone Apr 14, 2015

@rsc rsc removed the go1.1 label Apr 14, 2015

@golang golang locked and limited conversation to collaborators Jun 24, 2016

This issue was closed.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
You can’t perform that action at this time.