使用类型断言
在
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 packagefunc 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}


