Golang json 解析
背景:
最近在用iris做web端的時候,遇到了這麼一個問題,前端傳過來的json串如下:
{
"Name": "jiankunking",
"Age": 12,
"BlogArticles": {
"one": {
"Detail": "csdn blog",
"Author": "jiankunking",
"Urls": {
"1": "http://blog.csdn.net/jiankunking/article/details/52143504",
"2": "http://blog.csdn.net/jiankunking/article/details/52673302",
"3": "http://blog.csdn.net/jiankunking/article/details/45479105"
}
},
"two": {
"Detail": "CSDN BLOG",
"Author": "JIANKUNKING",
"Urls": {
"1": "http://blog.csdn.net/jiankunking/article/details/52684722",
"2": "http://blog.csdn.net/jiankunking/article/details/78808978"
}
}
}
}
我用如下的結構接收:
type Person struct {
Name string
Age int
BlogArticles map[string]interface{}
}
type BlogArticle struct {
Detail string
Author string
Urls map[string]string
}
從json結構來看,結構Person中BlogArticles map值的結構均符合 結構BlogArticle ,那我是不是可以這麼做呢?
blogArticle3 := person.BlogArticles["one"].(BlogArticle)
//此時輸出person.BlogArticles["one"]型別,可知,
//person.BlogArticles["one"]是map[string]interface {}
//雖然,看起來結構一樣,但map[string]interface {}與BlogArticle卻無法轉換
答案是否定的,錯誤資訊如下:
panic: interface conversion: interface {} is map[string]interface {}, not main.BlogArticle
那麼正確的做法應該如何處理呢?在接收資料的時候,用如下結構接收:
type BlogArticle struct {
Detail string
Author string
Urls map[string]string
}
type PersonCorrect struct {
Name string
Age int
BlogArticles map[string]BlogArticle
}
這時輸出person.BlogArticles[“one”]的型別可知:
fmt.Println(typeof(personCorrect.BlogArticles["one"]))
//結果
//main.BlogArticle
演示程式碼如下:
https://github.com/jiankunking/backups/blob/master/decode.go
那麼,”encoding/json”到底是怎麼反序列化的呢?
在decode結構註釋中,找到以下介紹:
// Unmarshal parses the JSON-encoded data and stores the result
// in the value pointed to by v.
//
// Unmarshal uses the inverse of the encodings that
// Marshal uses, allocating maps, slices, and pointers as necessary,
// with the following additional rules:
//
// To unmarshal JSON into a pointer, Unmarshal first handles the case of
// the JSON being the JSON literal null. In that case, Unmarshal sets
// the pointer to nil. Otherwise, Unmarshal unmarshals the JSON into
// the value pointed at by the pointer. If the pointer is nil, Unmarshal
// allocates a new value for it to point to.
//
// To unmarshal JSON into a value implementing the Unmarshaler interface,
// Unmarshal calls that value's UnmarshalJSON method, including
// when the input is a JSON null.
// Otherwise, if the value implements encoding.TextUnmarshaler
// and the input is a JSON quoted string, Unmarshal calls that value's
// UnmarshalText method with the unquoted form of the string.
//
// To unmarshal JSON into a struct, Unmarshal matches incoming object
// keys to the keys used by Marshal (either the struct field name or its tag),
// preferring an exact match but also accepting a case-insensitive match.
// Unmarshal will only set exported fields of the struct.
//
// To unmarshal JSON into an interface value,
// Unmarshal stores one of these in the interface value:
//
// bool, for JSON booleans
// float64, for JSON numbers
// string, for JSON strings
// []interface{}, for JSON arrays
// map[string]interface{}, for JSON objects
// nil for JSON null
//
// To unmarshal a JSON array into a slice, Unmarshal resets the slice length
// to zero and then appends each element to the slice.
// As a special case, to unmarshal an empty JSON array into a slice,
// Unmarshal replaces the slice with a new empty slice.
//
// To unmarshal a JSON array into a Go array, Unmarshal decodes
// JSON array elements into corresponding Go array elements.
// If the Go array is smaller than the JSON array,
// the additional JSON array elements are discarded.
// If the JSON array is smaller than the Go array,
// the additional Go array elements are set to zero values.
//
// To unmarshal a JSON object into a map, Unmarshal first establishes a map to
// use. If the map is nil, Unmarshal allocates a new map. Otherwise Unmarshal
// reuses the existing map, keeping existing entries. Unmarshal then stores
// key-value pairs from the JSON object into the map. The map's key type must
// either be a string, an integer, or implement encoding.TextUnmarshaler.
//
// If a JSON value is not appropriate for a given target type,
// or if a JSON number overflows the target type, Unmarshal
// skips that field and completes the unmarshaling as best it can.
// If no more serious errors are encountered, Unmarshal returns
// an UnmarshalTypeError describing the earliest such error.
//
// The JSON null value unmarshals into an interface, map, pointer, or slice
// by setting that Go value to nil. Because null is often used in JSON to mean
// ``not present,'' unmarshaling a JSON null into any other Go type has no effect
// on the value and produces no error.
//
// When unmarshaling quoted strings, invalid UTF-8 or
// invalid UTF-16 surrogate pairs are not treated as an error.
// Instead, they are replaced by the Unicode replacement
// character U+FFFD.
//
原始碼地址如下:
https://github.com/golang/go/blob/release-branch.go1.8/src/encoding/json/decode.go
但並未說明當unmarshal a JSON object into a map時,如果map中的value是interface{}時,該如何處理。
具體處理程式碼可以看原始碼func Unmarshal(data []byte, v interface{}) error {}處理的整個流程。
個人微信公眾號:
作者:jiankunking 出處:http://blog.csdn.net/jiankunking
相關文章
- Golang 流式解析 JsonGolangJSON
- 細說 Golang 的 JSON 解析GolangJSON
- golang 解析php輸出json相容問題GolangPHPJSON
- golang json 示例GolangJSON
- Golang 的 JSON 包GolangJSON
- golang json 效能分析GolangJSON
- golang bufio解析Golang
- json解析模組JSON
- json解析boolJSON
- js json解析JSON
- Exercise:JSON解析JSON
- golang json處理問題GolangJSON
- 再測Golang的JSON庫GolangJSON
- Golang : cobra 包解析Golang
- Golang 中使用 JSON 的小技巧GolangJSON
- Swift iOS : 解析jsonSwiftiOSJSON
- 用JS解析JSONJSON
- java解析json listJavaJSON
- Swift Json解析探索SwiftJSON
- Java解析Json字串JavaJSON字串
- json資料解析JSON
- cJSON:解析JSONJSON
- golang url解析問題Golang
- golang解析html出錯GolangHTML
- 比 encoding/json 更快地解析 jsonEncodingJSON
- Golang高效能json包:easyjsonGolangJSON
- golang中struct、json、map互相轉化GolangStructJSON
- golang讀取檔案的json資料流,並解析到struct,儲存到資料庫GolangJSONStruct資料庫
- Flutter 中的 JSON 解析FlutterJSON
- oracle json 解析函式OracleJSON函式
- 解析大資料json大資料JSON
- ajax解析json物件集合JSON物件
- 課程 1: JSON 解析JSON
- JsonPath —— JSON 解析神器JSON
- 使用jsoncpp解析jsonJSON
- JSON 之FastJson解析JSONAST
- iOS開發-JSON解析iOSJSON
- Json解析之Gson庫JSON