将界面转换为另一个并复制内容

I've got the following method:

func ValidateParam(conf map[string]interface{}, paramName string, out interface{}) error {
    param, ok := conf[paramName]

    if !ok {
        return errors.New("some error")
    }

    // ...
}

I would like to be able to call it like so:

myVar := "some text"
err := ValidateParam(conf, "my_var_param", &myVar)

myOtherVar := &MyStruct{}
err := ValidateParam(conf, "my_struct_param", myOtherVar)

The idea is:

  • Get the param using the conf map
  • Check that this param could be converted into the same type as out
  • Hydrate out using the param

=> It is kind of the same process as for json.Unmarshal(data, &myVar) or when doing a query with mgo query.Collection("col").One(&myVar)

I can't find how to achieve this, any help would be more than welcome.

Cheers

One option is to use the reflect package:

The basic idea is to create reflect.Values for input and output, check if input is assignable to output and then assign.

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