Leggere file JSON in Golang
Adesso sto usando Go per scrivere i miei programmi e avevo bisogno di leggere dei file JSON. Uhm.. Come si fa? Per fortuna la libreria standard di Go è molta completa e ci rende le cose piú semplice. Ecco qua come ho risolto il problema.
Questo è il mio file JSON chiamato tentacles.json
[
{
"name": "Purple Tentacle",
"description": "A mutant monster and lab assistant created by mad scientist Dr. Fred Edison."
},
{
"name": "Green Tentacle",
"description": "Harmless and friendly brother of Purple Tentacle."
},
{
"name": "Bernard Bernoulli",
"description": "Green Tentacle's friend, he's a nerd with glasses."
}
]
Adesso seguiamo la buona prassi della TDD (test-driven development) e prima di tutto scriviamo una funzione di test in json_test.go
package main
import "testing"
// TestReadJSON testing read from JSON file
func TestReadJSON(t *testing.T) {
tentacles := getTentacles()
tentacle := tentacles[2]
expectedName := "Bernard Bernoulli"
expectedDescription := "Green Tentacle's friend, he's a nerd with glasses."
if expectedName != tentacle.Name {
t.Errorf("Tentacle.name == %q, want %q",
tentacle.Name, expectedName)
}
if expectedDescription != tentacle.Description {
t.Errorf("Tentacle.description == %q, want %q",
tentacle.Description, expectedDescription)
}
}
ovviamente il test ci darà un errore perché dobbiamo ancora scrivere la funzione getTentacles()
.
$ go test -v
# dd-golang/json
./json_test.go:7: undefined: getTentacles
FAIL dd-golang/json [build failed]
e questo è il programma main in json.go
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
)
// Tentacle a character from Day of Tentacles
type Tentacle struct {
Name string `json:"name"`
Description string `json:"description"`
}
func (t Tentacle) toString() string {
bytes, err := json.Marshal(t)
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
return string(bytes)
}
func getTentacles() []Tentacle {
tentacles := make([]Tentacle, 3)
raw, err := ioutil.ReadFile("./tentacles.json")
if err != nil {
fmt.Println(err.Error())
os.Exit(1)
}
json.Unmarshal(raw, &tentacles)
return tentacles
}
func main() {
tentacles := getTentacles()
fmt.Println(tentacles)
for _, te := range tentacles {
fmt.Println(te.toString())
}
}
Adesso il test passa senza problemi
$ go test -v
=== RUN TestReadJSON
--- PASS: TestReadJSON (0.00s)
PASS
ok dd-golang/json 0.002s
questo è l'output del programma
$ go run json.go
[{Purple Tentacle A mutant monster and lab assistant created by mad scientist Dr. Fred Edison.} {Green Tentacle Harmless and friendly brother of Purple Tentacle.} {Bernard Bernoulli Green Tentacle's friend, he's a nerd with glasses.}]
{"name":"Purple Tentacle","description":"A mutant monster and lab assistant created by mad scientist Dr. Fred Edison."}
{"name":"Green Tentacle","description":"Harmless and friendly brother of Purple Tentacle."}
{"name":"Bernard Bernoulli","description":"Green Tentacle's friend, he's a nerd with glasses."}
Come puoi vedere, ho usato una struct per memorizzare i dati JSON, e se hai bisogno di convertire JSON a strutture di GO, ti consiglio di andare alla pagina JSON-to-Go.
Danilo