1 回答
TA贡献1808条经验 获得超4个赞
使用类型断言
在您的unmarshalJSON()函数中,参数的s行为类似于局部变量。当你为它分配一些东西时:
s = result
它只会改变局部变量的值。
由于您希望它改变 a 的值*map[string]interface{}并且这就是您传递给它的值,因此您可以使用简单的类型断言从中获取映射指针,并将此指针传递给json.Unmarshal():
func unmarshalJSON(in []byte, s interface{}) error {
if m, ok := s.(*map[string]interface{}); !ok {
return errors.New("Expecting *map[string]interface{}")
} else {
return json.Unmarshal(in, m)
}
}
在Go Playground上尝试修改后的工作示例。
只是传递
还要注意,但是这完全没有必要,因为json.Unmarshal()它也被定义为将目的地作为 type 的值interface{},与您拥有的相同。所以你甚至不需要做任何事情,只需传递它:
func unmarshalJSON(in []byte, s interface{}) error {
return json.Unmarshal(in, s)
}
在Go Playground上试试这个。
带有函数类型的变量
有趣的是,您和库函数的签名是相同的:unmarshalJSON()json.Unmarshal()
// Yours:
func unmarshalJSON(in []byte, s interface{}) error
// json package
func Unmarshal(data []byte, v interface{}) error
这意味着还有另外一个选择,那就是你可以使用一个命名的变量unmarshalJSONa的函数类型,并只分配函数值json.Unmarshal:
var unmarshalJSON func([]byte, interface{}) error = json.Unmarshal
现在你有一个unmarshalJSON函数类型的变量,你可以像调用函数一样调用它:
err := unmarshalJSON(b, &s)
在Go Playground上试试这个函数值。
现在开始你的unmarshalYAML()功能
在你unmarshalYAML()你犯了同样的错误:
s = cleanUpInterfaceMap(result)
这只会更改您的局部s变量(参数)的值,而不会“填充”传递给unmarshalYAML().
使用上面详述的类型断言技术从s interface{}参数中获取指针,一旦获得指针,就可以更改指向的对象(“外部”映射)。
func unmarshalYAML(in []byte, s interface{}) error {
var dest *map[string]interface{}
var ok bool
if dest, ok = s.(*map[string]interface{}); !ok {
return errors.New("Expecting *map[string]interface{}")
}
var result map[interface{}]interface{}
if err := yaml.Unmarshal(in, &result); err != nil {
return err
}
m := cleanUpInterfaceMap(result)
// m holds the results, dest is the pointer that was passed to us,
// we can just set the pointed object (map):
*dest = m
return nil
}
- 1 回答
- 0 关注
- 235 浏览
添加回答
举报
