So, having found that Go (aka Golang) is a decendant of Modula-2 and has some pretty nifty features, I decided that Golang was the way to Go (if you will pardon the expression).
The next thing that I do is head straight for the target, reading just enough to get me there. If the journey is a happy one I may flesh things out later, but when you are relying on the internet and googling, the search results are a bit like flicking through a book - but not as good because sometimes a book yields a gem that you weren't looking for.
The project is made of multiple servers (raspberry pi) doing crazy stuff all talking to each other as well as hardware and Arduinos. The first server was a sound player controlled by other remote servers. It loaded a name->filename map from a JSON file. Not too tricky.
The second one needed some routing tables loaded. I wanted pure object arrays loaded from JSON.
Note : You can't use an Array, you need a SLICE. Arrays are fixed size.
I Googled and came across lots of people on StackOverflow asking the same question.
A lot of the answers and questions revolved around interface{} which I tried and got working but it seemed a bit tricky because there are multiple type conversions involved - silly when all records are the same type. And there seemed to be NOBODY telling how to do it.
So, if you are trying to load an
The data record I want to load
type command_record struct {
Source string
What string
Condition string
Value string
Host string
Action string
}
Which we will represent in JSON as
[
{
"Source": "sensor",
"What": "temp",
"Condition": "GT",
"Value": "35",
"Host": "sensor",
"Action": "REDON"
},
{
"Source": "host",
"What": "sensoralarm",
"Condition": "NIL",
"Value": "0",
"Host": "sensor",
"Action": "BLUOFF"
}
]
So the slice is represented as
var sensor_script *[]command_record
Note the * which means we are only declaring a pointer.
And we read the file into a slice of bytes
file, e := ioutil.ReadFile("./sensor.json")
if e != nil {
fmt.Printf("File error %v\n", e)
os.Exit(1)
}
Then we convert it objects using json.Unmarshal and print it just to show it works
json.Unmarshal(file, &sensor_script)
for _, v := range *sensor_script {
fmt.Println(v.Source)
fmt.Println(v.What)
fmt.Println(v.Condition)
fmt.Println(v.Value)
fmt.Println(v.Host)
fmt.Println(v.Action)
fmt.Println("=========")
}
And, after all that time - it is that simple. And I am sure that many many people have figured it out within ten minutes, but others have too google it and waste a lot of time. This is for them.
The code and a sample JSON file can be found on Github at https://github.com/DaveAppleton/LoadObjectSliceFromJson
Cannot tell you how helpful this post was. I'll make sure to point to your post for any related posts I do in the future. Thank you!
ReplyDelete