2017-11-25 270 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

    相關問題