0

All I looking to do is to create an array of struct Response from a json encoded file.

the file that contains json data looks like this.

cat init.txt

{"events": [{"action":"cpr","id":69,"sha1":"abc","cpr":"cpr_data0"},{"action":"cpr","id":85,"sha1":"def","cpr":"cpr_data1"}]}

The way I have gone about approaching this is

  • I created a response of type map[string][]Response

  • .. decoded the JSON from the file

  • .. created a responseStruct of type []Response

But somehow when I inspect the Value they all look 0 or empty

map[events:[{ 0 } { 0 }]

What is wrong with the approach mentioned above.

type Response struct {
  action string `json:"action"`
  id     int64  `json:"id"`
  sha1   string `json:"sha1"`
  cpr    string `json:"cpr"`
}

func main() {
  file, err := os.Open("init.txt")
  if err != nil {
    fmt.Println(err)
    os.Exit(1)
  }
  var response map[string][]Response
  err = json.NewDecoder(file).Decode(&response)
  if err != nil {
    fmt.Println(err)
    os.Exit(1)
  }

  var responseArray []Response
  responseArray = response["events"]
  for _, responseStruct := range responseArray {
    fmt.Println("id =", responseStruct.id)
    fmt.Println("action =", responseStruct.action)
    fmt.Println("sha1 = ", responseStruct.sha1)
    fmt.Println("cpr =", responseStruct.cpr)
    fmt.Println("==========")
  }
  fmt.Println(response)
}

Well If I modify the struct to look like this it works

type Response struct {
  Action string `json:"action"`
  ID     int64  `json:"id"`
  Sha1   string `json:"sha1"`
  Cpr    string `json:"cpr"`
}

So my question is this how the stuff would work, can't I get the above code to work in the way it is?

Ratatouille
  • 1,372
  • 5
  • 23
  • 50
  • please check https://stackoverflow.com/a/17982725/4466350. As a side note, this is not an array, this is a slice. The difference being that an array has a fixed length. –  Jul 28 '18 at 12:17
  • @mh-cbon Understood. – Ratatouille Jul 28 '18 at 12:31

2 Answers2

2

Go has the notion of public and private fields in objects, and the only distinction is whether they start with an initial capital letter or not. This applies to not just code modules but also the reflect package and things that use it. So in your initial version

type Response struct {
  action string `json:"action"`
  ...
}

nothing outside your source package, not even the "encoding/json" module, can see the private fields, so it can't fill them in. Changing these to public fields by capitalizing Action and the other field names makes them visible to the JSON decoder.

David Maze
  • 130,717
  • 29
  • 175
  • 215
0

Lowercase struct elements in golang are private, Hence json decoder (which is an external package) can't access them. Its able to create the struct object but not able to set values. They appear zero because they 0 is default value.

avertocle
  • 541
  • 4
  • 6