As usual, with a new project arriving my first question is "what can we learn on this one?"
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
array slice of objects from a JSON file - bearing in mind I have been doing this for a couple of weeks with a lot of that time goofing off, here it is....
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.