【发布时间】:2015-12-19 02:54:35
【问题描述】:
假设我有这种类型:
type Foo struct{
Bar string `json:"bar"`
}
我想将这个 json 解组到其中:
in := []byte(`{"bar":"aaa", "baz":123}`)
foo := &Foo{}
json.Unmarshal(in,foo)
会成功的。我至少想知道在处理过程中跳过了一些字段。有什么好的方法可以访问这些信息吗?
【问题讨论】:
假设我有这种类型:
type Foo struct{
Bar string `json:"bar"`
}
我想将这个 json 解组到其中:
in := []byte(`{"bar":"aaa", "baz":123}`)
foo := &Foo{}
json.Unmarshal(in,foo)
会成功的。我至少想知道在处理过程中跳过了一些字段。有什么好的方法可以访问这些信息吗?
【问题讨论】:
您可能知道,您可以将任何有效的 json 解组为 map[string]interface{}。解组到 Foo 的实例后,已经没有可用的元数据,您可以在其中检查被排除的字段或类似的东西。但是,您可以解组这两种类型,然后检查映射中与 Foo 上的字段不对应的键。
in := []byte(`{"bar":"aaa", "baz":123}`)
foo := &Foo{}
json.Unmarshal(in,foo)
allFields := &map[string]interface{}
json.Unmarshal(in, allFields)
for k, _ := range allFields {
fmt.Println(k)
// could also use reflect to get field names as string from Foo
// the get the symmetric difference by nesting another loop here
// and appending any key that is in allFields but not on Foo to a slice
}
【讨论】:
allFields 映射并使用递归算法将所有字段从具体类型中的嵌套结构中取出来实现通用解决方案。获取字段名称的仅供参考可能会觉得这很有用; stackoverflow.com/questions/24337145/…
interface{} 实现UnmarshalJSON,将调用链接到它的正常版本,但不是在反映类型并检查传入字符串中的所有字段之前。如果您访问 json 标记,则可以通过执行 tag = " + tag + ": 来保证匹配非常好(ofc 在那里正确引用,不知道如何在评论中做到这一点)。输入字符串不会真正引起冲突,因为它们需要转义,所以我认为 string.Contains 相当可靠。