英文:
UnmarshalJSON any type from []interface{} possible?
问题
当你将JSON解组为[]interface{}
时,除了一些标准类型(如bool、int和string)之外,是否有任何自动检测类型的方法?
我注意到以下情况,假设我将[uuid.UUID, bool]
进行编组,然后得到的JSON如下所示:
[[234,50,7,116,194,41,64,225,177,151,60,195,60,45,123,106],true]
当我再次解组时,通过reflect
显示的类型如下:
[]interface{}, bool
我不明白为什么它选择了[]interface{}
。如果它无法检测到类型,那么它不应该至少是interface{}
吗?
无论如何,我的问题是,当目标类型为[]interface{}
时,是否可能解组任何类型?对于标准类型(如string、bool、int),似乎可以工作,但对于自定义类型,我认为这是不可能的,对吗?你可以定义自定义的JSON编组/解组方法,但这仅适用于将其解码为目标类型,以便可以查找要使用的自定义编组/解组方法。
英文:
When you unmarshal JSON to []interface{}
is there any way to automatically detect the type besides some standard types like bool, int and string?
What I noticed is the following, Let's say I marshal [uuid.UUID, bool]
then the JSON I get looks like:
[[234,50,7,116,194,41,64,225,177,151,60,195,60,45,123,106],true]
When I unmarshal it again, I get the types as shown through reflect
:
[]interface{}, bool
I don't understand why it picked []interface{}
. If it cannot detect it, shouldn't it be at least interface{}
?
In any case, my question is, is it possible to unmarshal any type when the target is of type []interface{}
? It seems to work for standard types like string, bool, int but for custom types I don't think that's possible, is it? You can define custom JSON marshal/unmarshal methods but that only works if you decode it into a target type so that it can look up which custom marshal/unmarshal methods to use.
答案1
得分: 3
你可以将任何类型解组为interface{}
类型的值。如果你使用[]interface{}
类型的值,你只能将JSON数组解组到其中,但是是的,数组的元素可以是任何类型。
由于你使用的是interface{}
或[]interface{}
类型,是的,类型信息是不可用的,这取决于encoding/json
包选择最合适的类型。例如,对于JSON对象,它会选择map[string]interface{}
类型。默认类型的完整列表在json.Unmarshal()
中有文档记录:
为了将JSON解组为接口值,Unmarshal将其中之一存储在接口值中:
对于JSON布尔值,存储bool类型 对于JSON数字,存储float64类型 对于JSON字符串,存储string类型 对于JSON数组,存储[]interface{}类型 对于JSON对象,存储map[string]interface{}类型 对于JSON null,存储nil
显然,如果你的JSON编组/解组逻辑需要一些预处理/后处理,json
包将无法奇迹般地找到它。它只能在你解组为特定类型的值(实现了json.Unmarshaler
)时了解到这些信息。json
包仍然能够将它们解组为默认类型,但是自定义逻辑显然不会对它们运行。
英文:
You can unmarshal any type into a value of type interface{}
. If you use a value of type []interface{}
, you can only unmarshal JSON arrays into it, but yes, the elements of the array may be of any type.
Since you're using interface{}
or []interface{}
, yes, type information is not available, and it's up to the encoding/json
package to choose the best it sees fit. For example, for JSON objects it will choose map[string]interface{}
. The full list of default types is documented in json.Unmarshal()
:
> 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
Obviously if your JSON marshaling/unmarshaling logic needs some pre- / postprocessing, the json
package will not miraculously find it out. It can know about those only if you unmarshal into values of specific types (which implement json.Unmarshaler
). The json
package will still be able to unmarshal them to the default types, but custom logic will obviously not run on them.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论