简体   繁体   中英

Set struct field of pointer type

The task is pretty simple. I have struct for model Foo, and one for it's representation:

type Foo struct {
  FooId string
  Bar   string
  Baz   *string
  Salt  int64
}

type FooView struct {
  FooId *string `json: "foo_id"`
  Bar   *string `json: "bar"`
  Baz   *string `json: "baz"`
}

As you may see, there is Salt field which I want to hide, change JSON field names, and do all the fields optional. The target method should fill FooView using Foo like this:

func MirrorFoo(foo Foo) (*FooView, error) {
  return &FooView{
    FooId: &foo.FooId,
    Bar:   &foo.Bar,
    Baz:   foo.Baz,
  }, nil
}

And now, I want to do the same with Go reflect:

func Mirror(src interface{}, dstType reflect.Type) (interface{}, error) {
  zeroValue := reflect.Value{}
  srcValue := reflect.ValueOf(src)
  srcType := srcValue.Type()
  dstValue := reflect.New(dstType)
  dstValueElem := dstValue.Elem()
  for i := 0; i < srcType.NumField(); i++ {
    srcTypeField := srcType.Field(i)
    srcValueField := srcValue.FieldByName(srcTypeField.Name)
    dstField := dstValueElem.FieldByName(srcTypeField.Name)

    // if current source field exists in destination type
    if dstField != zeroValue {
      srcValueField := srcValue.Field(i)
      if dstField.Kind() == reflect.Ptr && srcValueField.Kind() != reflect.Ptr {

        panic("???")

      } else {
        dstField.Set(srcValueField)
      }
    }
  }
  return dstValue.Interface(), nil
}

This code works fine when FooId is uuid.UUID in both types, but it fails when source is uuid.UUID and destination is *uuid.UUID, and now do not know how to overcome this.

Somehow I need to do analog of dstField.Set(reflect.ValueOf(&uuid.UUID{}...)) bit everything I've tried does not works. Any ideas?

Yep, Addr() worked for me, but without

reflect.Copy()

It's for arrays. I've instantiated new value using reflect.New() and.Set() current value. Address became available. It's completely black magic. Thanks for all.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM