0

I have the following code:

package main

import "encoding/json"
import "fmt"

type SuperNum struct {
    num string
}

func main() {
    byt := []byte(`{"num":"6.13"}`)

    var dat SuperNum

    if err := json.Unmarshal(byt, &dat); err != nil {
        panic(err)
    }
    fmt.Printf("%+v", dat) // I expect this to have a `num` attribute
}

Output:

{num:}
Program exited.

You can run this code in the golang playground.

Because I'm setting a num property in the struct and in the JSON and they're both strings, I would have expected the dat struct to have a num property, with 'hello', but it doesn't.

What am I doing wrong? What in my mental model of how this should work is incorrect?

EDIT

I tried adding the json signature to the struct, but it makes no difference (no idea what that actually does).

type SuperNum struct {
    num string `json:"num"`
}
Jorge Silva
  • 4,574
  • 1
  • 23
  • 42

3 Answers3

4

num is by convention not exported as it is lower case. Change it to Num and you are able to inspect the result.

type SuperNum struct {
    Num string
}                                                                                   
iltempo
  • 15,718
  • 8
  • 61
  • 72
2

Just change num to Num. The lowercase properties of the structures are not visible.

Go playground

Salvador Dali
  • 214,103
  • 147
  • 703
  • 753
1

When unmarhalling JSON structures, the properties that you're mapping on must be public (remember that in Go, public and private visibility of struct and module members is denoted by the member's name being upper or lower camel case.

So, first of all, your struct must be defined like this:

type SuperNum struct {
    Num string  // <- note the capital "N"
}

With this struct, the JSON marshaller will expect the JSON property to be also named Num. In order to configure a different property name (like the lowercased num in your example), use the json annotation for that struct member:

type SuperNum struct {
    Num string `json:"num"`
}
helmbert
  • 35,797
  • 13
  • 82
  • 95