Go语言 如何使用反射将嵌套结构的修改值赋给结构

o8x7eapl  于 2023-02-06  发布在  Go
关注(0)|答案(1)|浏览(179)

我有这样的结构

type Library struct {
    Book            Book           
    Owner           Owner           
    Editorial       Editorial
}

我不得不将自动生成的Book结构的一个标记从category修改为categoryID

type Book struct {
    ID             string           `json:"id"`
    Title          string           `json:"title"`
    Description    string           `json:"description"`
    Category       string           `json:"category"`
}

我的问题是,在修改了这些字段并得到正确的Book结构后,我如何将其设置为Library.Book中的新结构?
我的代码:

func renameTags(p any, m map[string]string) any {

    rv := reflect.ValueOf(p)
    re := rv.Elem()
    rt := rv.Elem().Type()

    fields := make([]reflect.StructField, rt.NumField())
    for i := range fields {
        f := rt.Field(i) // Book i == 0

        if f.Type.Kind() == reflect.Struct && f.Type.Name() == "Book" {
            fields2 := make([]reflect.StructField, f.Type.NumField()) // f == Book
            for j := 0; j < f.Type.NumField(); j++ {
                subField := f.Type.Field(j)
                tag := subField.Tag.Get("json")
                if v, ok := m[tag]; ok {
                    subField.Tag = reflect.StructTag(`json:"` + v + `"`)
                }
                fields2[j] = subField // change structure of Book
            }

            // here how to append new structure to f ?

            //kk := reflect.StructOf(fields2).Elem()

        }

        fields[i] = f
    }

    st := reflect.StructOf(fields)
    return rv.Convert(reflect.PtrTo(st)).Interface()
}

如有任何建议,我们将不胜感激,谢谢!

iqjalb3h

iqjalb3h1#

你可以使用reflect.new来创建一个修改后的结构的新示例,然后将值赋给原始结构中的相应字段。

func renameTags(p any, m map[string]string) any {

    rv := reflect.ValueOf(p)
    re := rv.Elem()
    rt := rv.Elem().Type()

    fields := make([]reflect.StructField, rt.NumField())
    for i := range fields {
        f := rt.Field(i) // Book i == 0

        if f.Type.Kind() == reflect.Struct && f.Type.Name() == "Book" {
            fields2 := make([]reflect.StructField, f.Type.NumField()) // f == Book
            for j := 0; j < f.Type.NumField(); j++ {
                subField := f.Type.Field(j)
                tag := subField.Tag.Get("json")
                if v, ok := m[tag]; ok {
                    subField.Tag = reflect.StructTag(`json:"` + v + `"`)
                }
                fields2[j] = subField // change structure of Book
            }

            newStruct := reflect.New(reflect.StructOf(fields2))
            re.Field(i).Set(newStruct)
        }

        fields[i] = f
    }

    st := reflect.StructOf(fields)
    return rv.Convert(reflect.PtrTo(st)).Interface()
}

相关问题