With JSON we have a fast way to store object models as text. Strings, ints—any objects—are supported. Go provides a built-in encoding library.
With Unmarshal()
, we convert data from JSON to a Go struct
. And with Marshal, we perform the opposite conversion from a Go object to JSON data.
To start, suppose we have a JSON string
, and wish to convert it to a Go object. We can use Unmarshal()
, and then treat the object as any other.
package main
import (
"encoding/json"
"fmt"
)
type AnimalData struct {
Bird int
Cat string
}
func main() {
// Input data.
text := "{\"Bird\":10,\"Cat\":\"Fuzzy\"}"
bytes := []byte(text)
// Get struct from string.
var animal AnimalData
json.Unmarshal(bytes, &animal)
// Print result.
fmt.Printf("BIRD = %v, CAT = %v", animal.Bird, animal.Cat)
fmt.Println()
}BIRD = 10, CAT = Fuzzy
Continuing on, we convert a Go struct
into JSON data. We have a type Box, which is a custom struct
. It has 4 fields—a Width, Height, Color and a bool
called Open.
string
and display them with fmt.Println
.package main
import (
"encoding/json"
"fmt"
)
type Box struct {
Width int
Height int
Color string
Open bool
}
func main() {
// Create an instance of the Box struct.
box := Box{
Width: 10,
Height: 20,
Color: "blue",
Open: false,
}
// Create JSON from the instance data.
// ... Ignore errors.
b, _ := json.Marshal(box)
// Convert bytes to string.
s := string(b)
fmt.Println(s)
}{"Width":10,"Height":20,"Color":"blue","Open":false}
Here we take JSON data (in bytes) and convert it to Go objects. The string
keys in the JSON are matched to the field names in the structs.
string
as text. We then convert it to a byte slice with a conversion.Unmarshal()
. We display their Id and Name fields.package main import ( "encoding/json" "fmt" ) type Language struct { Id int Name string } func main() { // String contains two JSON rows. text := "[{\"Id\": 100, \"Name\": \"Go\"}, {\"Id\": 200, \"Name\": \"Java\"}]" // Get byte slice from string. bytes := []byte(text) // Unmarshal string into structs. var languages []Language json.Unmarshal(bytes, &languages) // Loop over structs and display them. for l := range languages { fmt.Printf("Id = %v, Name = %v", languages[l].Id, languages[l].Name) fmt.Println() } }Id = 100, Name = Go Id = 200, Name = Java
Int
arrayIn JSON we can have arrays that contain values (like 100, 200, 300). These are labeled with a key (like Positions). Here we handle an int
array and get an int
slice from it.
Result
contains an int
slice with field name Positions. This where the int
array values are placed.byte
array of JSON data into a single struct
. Finally we print values on the Result
struct
.package main
import (
"encoding/json"
"fmt"
)
type Result struct {
Positions []int
}
func main() {
// This JSON contains an int array.
text := "{\"Positions\": [100, 200, 300, -1]}"
// Get bytes.
bytes := []byte(text)
// Unmarshal JSON to Result struct.
var result Result
json.Unmarshal(bytes, &result)
// Our int array is filled.
fmt.Printf("Positions = %v", result.Positions)
fmt.Println()
// Print int array length.
fmt.Printf("Length = %v", len(result.Positions))
fmt.Println()
}Positions = [100 200 300 -1]
Length = 4
Usually we do not just want to display JSON strings to the console. We can use ioutil.WriteFile
after invoking json.Marshal
to write a JSON file to the disk.
int
fields. The JSON uses the field names from BoxData
.WriteFile
is the file permissions—this is just something you copy if you want to write a new file.package main
import (
"encoding/json"
"io/ioutil"
)
type BoxData struct {
Width int
Height int
}
func main() {
// Empty slice.
boxes := []BoxData{}
boxes = append(boxes, BoxData{Width: 10, Height: 20})
boxes = append(boxes, BoxData{Width: 5, Height: 30})
// Get JSON bytes for slice.
b, _ := json.Marshal(boxes)
// Write entire JSON file.
ioutil.WriteFile(`C:\programs\jsongo.json`, b, 0644)
}[{"Width":10,"Height":20},{"Width":5,"Height":30}]
With these JSON methods we convert Go objects to JSON and back again. The "encoding/json" package is powerful: it enables robust support for this lightweight format.