UnmarshalJSON可能来自[] interface {}的任何类型?

时间:2017-01-27 08:59:58

标签: json go reflection types

当您将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{}类型时,是否可以解组任何类型?它似乎适用于标准类型,如字符串,bool,int,但对于自定义类型,我不认为这是可能的,是吗?您可以定义自定义JSON marshal / unmarshal方法,但只有在将其解码为目标类型时才能使用它,以便它可以查找要使用的自定义编组/解组方法。

1 个答案:

答案 0 :(得分:3)

您可以将任何类型解组为interface{}类型的值。如果使用类型[]interface{}的值,则只能将JSON数组解组到其中,但是,数组的元素可以是任何类型。

由于您使用的是interface{}[]interface{},因此,类型信息不可用,并且encoding/json包可以选择其认为合适的最佳状态。例如,对于JSON对象,它将选择map[string]interface{}json.Unmarshal()中记录了完整的默认类型列表:

  

要将JSON解组为接口值,Unmarshal会将其中一个存储在接口值中:

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

显然,如果您的JSON编组/解组逻辑需要一些预处理/后处理,json包将不会奇迹般地找到它。只有当你解组特定类型的值(实现json.Unmarshaler)时,它才能知道这些。 json包仍然可以将它们解组为默认类型,但显然不会在它们上运行自定义逻辑。