我有以下方法:
func ValidateParam(conf map[string]interface{}, paramName string, out interface{}) error {
param, ok := conf[paramName]
if !ok {
return errors.New("some error")
}
// ...
}
我希望能够这样称呼它:
myVar := "some text"
err := ValidateParam(conf, "my_var_param", &myVar)
myOtherVar := &MyStruct{}
err := ValidateParam(conf, "my_struct_param", myOtherVar)
这个想法是:
conf
地图out
out
=>它与json.Unmarshal(data, &myVar)
或使用mgo query.Collection("col").One(&myVar)
进行查询时的流程相同
我无法找到如何实现这一点,任何帮助都会受到欢迎。
干杯
答案 0 :(得分:3)
一种选择是使用反射包:
基本思想是为输入和输出创建reflect.Values,检查输入是否可分配给输出然后分配。
func ValidateParam(conf map[string]interface{}, paramName string, out interface{}) error {
param, ok := conf[paramName]
if !ok {
return errors.New("some error")
}
// Output is pointer to value.
vo := reflect.ValueOf(out)
if vo.Kind() != reflect.Ptr {
return errors.New("out must be poitner")
}
vo = vo.Elem() // deref ptr
// Can input be assigned to output?
vi := reflect.ValueOf(param)
if !vi.Type().AssignableTo(vo.Type()) {
return fmt.Errorf("param %s of type %v is not assignable to %v", paramName, vi.Type(), vo.Type())
}
vo.Set(vi)
return nil
}