繁体   English   中英

在 golang 中使用反射一般修改结构字段

[英]Generically modify struct fields using reflection in golang

下面是一个使用反射 package 修改结构字段的方法,这适用于特定的结构类型

func modify(obj Car) interface{} {
        ty := reflect.TypeOf(obj)
        for i := 0; i < ty.NumField(); i++ {
            rval := reflect.Indirect(reflect.ValueOf(&obj))
            field := rval.Field(i)
            fieldType := field.Kind()
    
            switch fieldType {
            case reflect.String:
                field.SetString("")
            case reflect.Int:
                field.SetInt(0)
            case reflect.Ptr:
                field.Set(reflect.ValueOf(nil))
    
            }
        }
        return obj
    }

修改签名为

func modify(obj interface{}) interface{} {

导致恐慌:反映:在接口值上调用 reflect.Value.Field

在线

 field := rval.Field(i)

https://go.dev/play/p/pGfKtIg5RUp它与签名一起使用

func modify(obj Car) interface{} {

https://go.dev/play/p/31Oh6WLmlGP

为什么编译时类型会修改行为? 这里的目标是根据结构标签屏蔽某些字段。它可以包装一个端点,输入和 output 到被包装的方法可以是结构或指针,所以在上面的情况下,两个调用都应该工作

modify(car)

modify(&car)

这就是它对值和指针类型的工作方式

func modify(obj interface{}) interface{} {
    rv := reflect.ValueOf(obj)
    trv := reflect.TypeOf(obj)
    value := reflect.New(rv.Type())
    if rv.Kind() == reflect.Pointer {
        rv = reflect.ValueOf(obj).Elem()
        trv = reflect.TypeOf(obj).Elem()
        value = reflect.New(rv.Type())
    }
    for i := 0; i < rv.NumField(); i++ {
        field := rv.Field(i)
        fieldType := field.Kind()
        v := value.Elem().Field(i)
        tag, _ := trv.Field(i).Tag.Lookup("es")
        if len(tag) != 0 {

            switch fieldType {
            case reflect.String:
                v.SetString(tag)
            case reflect.Int:
                v.SetInt(0)
            case reflect.Ptr:
                v.Set(reflect.ValueOf(nil))

            }
        } else {
            v.Set(field)
        }
    }

    return value
}

https://go.dev/play/p/C1pqw_UbPcG

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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