go提供对json
编码和解码的内置支持,包括内置和自定义数据类型。
我们将使用两个结构来演示下面的自定义类型的编码和解码。
首先,我们将看到基本数据类型到json字符串的编码。 这里有一些原子值的例子。
具体的每个函数,可参考示例中的代码 -
所有的示例代码,都放在
f:\worksp\golang
目录下。安装go编程环境请参考:http://www.h3.com/go/go_environment.html
json.go
的完整代码如下所示 -
package main
import "encoding/json"
import "fmt"
import "os"
// we'll use these two structs to demonstrate encoding and
// decoding of custom types below.
type response1 struct {
page int
fruits []string
}
type response2 struct {
page int `json:"page"`
fruits []string `json:"fruits"`
}
func main() {
// first we'll look at encoding basic data types to
// json strings. here are some examples for atomic
// values.
bolb, _ := json.marshal(true)
fmt.println(string(bolb))
intb, _ := json.marshal(1)
fmt.println(string(intb))
fltb, _ := json.marshal(2.34)
fmt.println(string(fltb))
strb, _ := json.marshal("gopher")
fmt.println(string(strb))
// and here are some for slices and maps, which encode
// to json arrays and objects as you'd expect.
slcd := []string{"apple", "peach", "pear"}
slcb, _ := json.marshal(slcd)
fmt.println(string(slcb))
mapd := map[string]int{"apple": 5, "lettuce": 7}
mapb, _ := json.marshal(mapd)
fmt.println(string(mapb))
// the json package can automatically encode your
// custom data types. it will only include exported
// fields in the encoded output and will by default
// use those names as the json keys.
res1d := &response1{
page: 1,
fruits: []string{"apple", "peach", "pear"}}
res1b, _ := json.marshal(res1d)
fmt.println(string(res1b))
// you can use tags on struct field declarations
// to customize the encoded json key names. check the
// definition of `response2` above to see an example
// of such tags.
res2d := &response2{
page: 1,
fruits: []string{"apple", "peach", "pear"}}
res2b, _ := json.marshal(res2d)
fmt.println(string(res2b))
// now let's look at decoding json data into go
// values. here's an example for a generic data
// structure.
byt := []byte(`{"num":6.13,"strs":["a","b"]}`)
// we need to provide a variable where the json
// package can put the decoded data. this
// `map[string]interface{}` will hold a map of strings
// to arbitrary data types.
var dat map[string]interface{}
// here's the actual decoding, and a check for
// associated errors.
if err := json.unmarshal(byt, &dat); err != nil {
panic(err)
}
fmt.println(dat)
// in order to use the values in the decoded map,
// we'll need to cast them to their appropriate type.
// for example here we cast the value in `num` to
// the expected `float64` type.
num := dat["num"].(float64)
fmt.println(num)
// accessing nested data requires a series of
// casts.
strs := dat["strs"].([]interface{})
str1 := strs[0].(string)
fmt.println(str1)
// we can also decode json into custom data types.
// this has the advantages of adding additional
// type-safety to our programs and eliminating the
// need for type assertions when accessing the decoded
// data.
str := `{"page": 1, "fruits": ["apple", "peach"]}`
res := response2{}
json.unmarshal([]byte(str), &res)
fmt.println(res)
fmt.println(res.fruits[0])
// in the examples above we always used bytes and
// strings as intermediates between the data and
// json representation on standard out. we can also
// stream json encodings directly to `os.writer`s like
// `os.stdout` or even http response bodies.
enc := json.newencoder(os.stdout)
d := map[string]int{"apple": 5, "lettuce": 7}
enc.encode(d)
}
执行上面代码,将得到以下输出结果 -
f:\worksp\golang>go run json.go
true
1
2.34
"gopher"
["apple","peach","pear"]
{"apple":5,"lettuce":7}
{"page":1,"fruits":["apple","peach","pear"]}
{"page":1,"fruits":["apple","peach","pear"]}
map[num:6.13 strs:[a b]]
6.13
a
{1 [apple peach]}
apple
{"apple":5,"lettuce":7}