2017-11-25 267 views
0

我有以下方法:接口转换到另一个和复制内容

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地图
  • 检查这个PARAM可以使用PARAM

被转换成相同的类型out

  • 水合物out =>它是一种相同的过程作为json.Unmarshal(data, &myVar)或与MgO的操作的方式查询时query.Collection("col").One(&myVar)

    我可以找不到如何做到这一点,任何帮助都不会受到欢迎。

    干杯

  • 回答

    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 
    } 
    

    playground example

    相关问题