一尘不染

如何动态创建少一个属性的结构?

go

有没有办法复制通用结构(即属性名称未知的结构)并跳过单个已知属性?

这是我所知道的:

  • 我函数的参数-我将称为参数myData-类型interface{}
  • myData 是一个结构。
  • myData具有已知的性质path
  • myData 具有0到6左右的其他属性,这些属性都不是先验的。
  • 一旦删除该path属性,那么“剩余”就是30种可能的结构类型之一。

所以我想剥离path出来myData(或更精确地进行复制,它省略path),所以生成的代码的各个位,尝试了结构迫使其可能的类型之一就能成功。

我已经找到了通过反射复制结构的示例,但是它们通常会创建一个 具有相同基础类型 的空结构,然后将其填充。因此,甚至有可能删除我概述的属性…?


阅读 217

收藏
2020-07-02

共1个答案

一尘不染

您可以用来reflect.StructOf根据字段列表动态创建结构。

package main

import (
    "fmt"
    "reflect"
)

type A struct {
    Foo string
    Bar int
    Baz bool // to be skipped
}

type B struct {
    Foo string
    Bar int
}

func main() {
    av := reflect.ValueOf(A{"hello", 123, true})

    fields := make([]reflect.StructField, 0)
    values := make([]reflect.Value, 0)
    for i := 0; i < av.NumField(); i++ {
        f := av.Type().Field(i)
        if f.Name != "Baz" {
            fields = append(fields, f)
            values = append(values, av.Field(i))
        }
    }

    typ := reflect.StructOf(fields)
    val := reflect.New(typ).Elem()
    for i := 0; i < len(fields); i++ {
        val.Field(i).Set(values[i])
    }

    btyp := reflect.TypeOf(B{})
    bval := val.Convert(btyp)

    b, ok := bval.Interface().(B)
    fmt.Println(b, ok)
}
2020-07-02