Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

strict json parser in golang

Tags:

json

go

In Go, I have some JSON from third-party API and then I'm trying to parse it:

b := []byte(`{"age":21,"married":true}`)
var response_hash map[string]string
_ = json.Unmarshal(b, &response_hash)

But it fails (response_hash becomes empty) and Unmarshal can handle only JSON with quotes:

b := []byte(`{"age":"21","married":"true"}`)
var response_hash map[string]string
_ = json.Unmarshal(b, &response_hash)

Is there any way to read the first version of JSON from third-party API?

like image 323
Kir Avatar asked Dec 18 '12 17:12

Kir


1 Answers

Go is a strongly typed language. You need to specify what types the JSON encoder is to expect. You're creating a map of string values but your two json values are an integer and a boolean value.

Here's a working example with a struct.

http://play.golang.org/p/oI1JD1UUhu

package main

import (
    "fmt"
    "encoding/json"
    )

type user struct {
    Age int
    Married bool
}

func main() {
    src_json := []byte(`{"age":21,"married":true}`)
    u := user{}
    err := json.Unmarshal(src_json, &u)
    if err != nil {
        panic(err)
    }
    fmt.Printf("Age: %d\n", u.Age)
    fmt.Printf("Married: %v\n", u.Married)
}

If you want to do it in a more dynamic manner you can use a map of interface{} values. You just have to do type assertions when you use the values.

http://play.golang.org/p/zmT3sPimZC

package main

import (
    "fmt"
    "encoding/json"
    )

func main() {
    src_json := []byte(`{"age":21,"married":true}`)
    // Map of interfaces can receive any value types
    u := map[string]interface{}{}
    err := json.Unmarshal(src_json, &u)
    if err != nil {
        panic(err)
    }
    // Type assert values
    // Unmarshal stores "age" as a float even though it's an int.
    fmt.Printf("Age: %1.0f\n", u["age"].(float64))
    fmt.Printf("Married: %v\n", u["married"].(bool))
}
like image 193
Daniel Avatar answered Oct 15 '22 00:10

Daniel