diff --git a/examples.txt b/examples.txt index 7aa85e3..bc1a60f 100644 --- a/examples.txt +++ b/examples.txt @@ -44,8 +44,7 @@ Collection Functions String Functions String Formatting Regular Expressions -Bytes -# JSON +JSON Time Epoch # Time Parsing / Formatting diff --git a/examples/json/json.go b/examples/json/json.go index 4172f58..ac9edad 100644 --- a/examples/json/json.go +++ b/examples/json/json.go @@ -1,39 +1,119 @@ +// Go offers built-in support for JSON encoding and +// decoding, including to and from built-in and custom +// data types. + 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() { - // data to bytes/string + + // 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)) - numB, _ := json.Marshal(1) - fmt.Println(string(numB)) + 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)) - arrD := []string{"apple", "peach", "pear"} - arrB, _ := json.Marshal(arrD) - fmt.Println(string(arrB)) + // 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)) - hshD := map[string]int{"apple": 5, "lettuce": 7} - hshB, _ := json.Marshal(hshD) - fmt.Println(string(hshB)) + mapD := map[string]int{"apple": 5, "lettuce": 7} + mapB, _ := json.Marshal(mapD) + fmt.Println(string(mapB)) - // string to data + // 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.0,"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{} - err := json.Unmarshal(byt, &dat) - if err != nil { + + // 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{}) - fmt.Println(strs) + 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) } diff --git a/examples/json/json.sh b/examples/json/json.sh new file mode 100644 index 0000000..0eaefee --- /dev/null +++ b/examples/json/json.sh @@ -0,0 +1,21 @@ +$ 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 strs:[a b]] +6 +a +&{1 [apple peach]} +apple +{"apple":5,"lettuce":7} + + +# We've covered the basic of JSON in Go here, but check +# out the [JSON and Go](http://blog.golang.org/2011/01/json-and-go.html) +# blog post and [JSON package docs](http://golang.org/pkg/encoding/json/) +# for more.