首页 > 解决方案 > 设置指针类型的结构字段

问题描述

任务很简单。我有模型 Foo 的结构,以及它的表示形式:

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"`
}

如您所见,我想隐藏一个 Salt 字段,更改 JSON 字段名称,并将所有字段设为可选。目标方法应该使用 Foo 填充 FooView ,如下所示:

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

现在,我想对 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
}

当 FooId 在两种类型中都是 uuid.UUID 时,此代码工作正常,但当源为 uuid.UUID 且目标为 *uuid.UUID 时,它会失败,现在不知道如何克服这个问题。

不知何故,我需要做 dstField.Set(reflect.ValueOf(&uuid.UUID{}...)) 的模拟,我尝试过的所有东西都不起作用。有任何想法吗?

标签: pointersgoreflectionset

解决方案


是的,Addr() 为我工作,但没有

reflect.Copy()

它用于数组。我已经使用 reflect.New() 和 .Set() 当前值实例化了新值。地址变得可用。这完全是黑魔法。谢谢大家。


推荐阅读