背景:
最近在用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 {}处理的整个流程。
个人微信公众号:
原文链接:https://www.f2er.com/go/187449.html作者:jiankunking 出处:http://blog.csdn.net/jiankunking