美文网首页Golang/Gin 学习
Golang-04 reflect struct ptr 学习笔

Golang-04 reflect struct ptr 学习笔

作者: 国服最坑开发 | 来源:发表于2019-08-28 20:14 被阅读0次

    0x01 reflect.TypeOf

    TypeOf, 看名知义: 读取对象的固有类型信息

    • 包名
    • 类型名
    • 属性信息
      • 属性名称
      • Tag
    • 方法信息
      • 方法名称
    type Man struct {
        Name string `hello:"world"`
    }
    
    func (m Man) String() string {
        return fmt.Sprintf("Man.Stringer() is %s", m.Name)
    }
    
    func (m Man) GoString() string {
        return fmt.Sprintf("Man.GoStringer() is %s", m.Name)
    }
    
    
    func main() {
        man := Man{Name: "Gorey"}
    
        to := reflect.TypeOf(man)
        fmt.Println("Name : " + to.Name())
        fmt.Println("kind : " + to.Kind().String())
        fmt.Println("pkg path : " + to.PkgPath())
    
        var i int
        for i = 0; i < to.NumMethod(); i++ {
            fmt.Println("method Name : " + to.Method(i).Name)
        }
        for i = 0; i < to.NumField(); i++ {
            f := to.Field(i)
            fmt.Printf("file Name : [%s],  tag :[%s]", f.Name, f.Tag)
        }
    }
    

    输出结果:

    Name : Man
    kind : struct
    pkg path : main
    method Name : GoString
    method Name : String
    file Name : [Name], tag :[hello:"world"]

    0x02 reflect.ValueOf

    接上面的代码,简单说一下结论:
    reflect.ValueOf 返回的是一个 Value 对象v

    重点在于:

    • 属性的名称信息: 要通过 v.Type().Field() 来读取
    • 属性的Tag: 要通过 v.Type().Field() 来读取
    • 属性的取值: 要通过 v.Field().Interface()来读取
    
    read(man)
    
    func read(obj interface{}) {
        v := reflect.ValueOf(obj)
        for i := 0; i < v.Type().NumField(); i++ {
            typeField := v.Type().Field(i)
            valueField := v.Field(i)
            value := valueField.Interface()
            fmt.Printf("fieldName :[%s], fieldValue :[%s] tag :[%s]\n", typeField.Name, value, typeField.Tag)
    
            switch vv := value.(type) {
            case int:
                fmt.Printf("this is a int : %d\n", vv)
            case string:
                fmt.Println("this is a string : " + vv)
            default:
                fmt.Println("other value")
            }
        }
    }
    
    

    输出结果:

    fieldName :[Name], fieldValue :[Gorey] tag :[hello:"world"]
    this is a string : Gorey

    0x03 关于 ptr

    Kind

    上面0x01,0x02两节的内容都是基于 Struct的操作.
    如果对指针类型进行反射操作的话,

    就必需, 先调用Elem()方法.

    • Sample :
            
            kind := reflect.TypeOf(s).Kind()
    
            // 参数为指针时:
            if kind == reflect.Ptr {
                v := reflect.ValueOf(s)
                for i := 0; i < v.Elem().Type().NumField(); i++ {
                    tag := v.Elem().Type().Field(i).Tag.Get(tagName)
                    if tag == "" || tag == "-" {
                        continue
                    }
                    validator := parseValidatorFromTag(tag)
                    valid, err := validator.Validate(v.Elem().Field(i).Interface())
                    if !valid && err != nil {
                        errs = append(errs, fmt.Errorf("%s%s", v.Elem().Type().Field(i).Name, err.Error()))
                    }
                }
            }
    
    
    

    相关文章

      网友评论

        本文标题:Golang-04 reflect struct ptr 学习笔

        本文链接:https://www.haomeiwen.com/subject/eoamectx.html