json.Unmarshal似乎并不注意struct标记

I have a JSON object that looks like this:

{"API version":"1.2.3"}

And I want to convert it to an object it using the json.Unmarshal() function in go. According to this blog post:

How does Unmarshal identify the fields in which to store the decoded data? For a given JSON key "Foo", Unmarshal will look through the destination struct's fields to find (in order of preference):

  • An exported field with a tag of "Foo" (see the Go spec for more on struct tags),
  • An exported field named "Foo", or
  • An exported field named "FOO" or "FoO" or some other case-insensitive match of "Foo".

This is confirmed by the unmarshal documentation.

Since "API version" has a space in it, which is not a valid go identifier, I used a tag on the field:

type ApiVersion struct {
 Api_version string "API version"
}

And I try to unmarshal it like so:

func GetVersion() (ver ApiVersion, err error) {

 // Snip code that gets the JSON

 log.Println("Json:",string(data))
 err = json.Unmarshal(data,&ver)
 log.Println("Unmarshalled:",ver);
}

The output is:

2014/01/06 16:47:38 Json: {"API version":"1.2.3"}
2014/01/06 16:47:38 Unmarshalled: {}

As you can see, the JSON isn't being marshalled into ver. What am I missing?

The encoding/json module requires that the struct tags be namespaced. So you instead want something like:

type ApiVersion struct {
    Api_version string `json:"API version"`
}

This is done so that the json struct tags can co-exist with tags from other libraries (such as the XML encoder).