严格的Golang JSON解析器

huangapple go评论92阅读模式
英文:

strict json parser in golang

问题

在Go语言中,我有一些来自第三方API的JSON数据,然后我试图解析它:

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

但是它失败了(response_hash变为空),而且Unmarshal只能处理带引号的JSON:

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

有没有办法读取来自第三方API的第一个版本的JSON数据?

英文:

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?

答案1

得分: 23

Go是一种强类型语言。您需要指定JSON编码器要期望的类型。您正在创建一个字符串值的映射,但是您的两个JSON值是一个整数和一个布尔值。

这是一个使用结构体的工作示例。

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)
}

如果您想以更动态的方式进行操作,可以使用接口值的映射。您只需要在使用这些值时进行类型断言。

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

package main

import (
    "fmt"
    "encoding/json"
)

func main() {
    src_json := []byte(`{"age":21,"married":true}`)
    // 接口值的映射可以接收任何值类型
    u := map[string]interface{}{}
    err := json.Unmarshal(src_json, &u)
    if err != nil {
        panic(err)
    }
    // 类型断言值
    // Unmarshal将"age"存储为浮点数,即使它是一个整数。
    fmt.Printf("Age: %1.0f\n", u["age"].(float64))
    fmt.Printf("Married: %v\n", u["married"].(bool))
}
英文:

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))
}

huangapple
  • 本文由 发表于 2012年12月19日 01:28:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/13938352.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定