美文网首页
Golang 反射个人理解

Golang 反射个人理解

作者: Good_Nine9 | 来源:发表于2021-05-06 14:51 被阅读0次

    (value) Elem()

    如果value是空接口类型,返回其具体的值
    如果是指针,返回指向的内容

    (type) Elem()

    如果type是array、chanel、slice,返回其元素type
    如果是map,返回 v 的type
    如果是指针,返回指向内容的type

    Indirect()

    如果是指针,返回其指向的值
    如果不是指针的话,返回Elem()

    func Indirect(v Value) Value {
        if v.Kind() != Ptr {
            return v
        }
        return v.Elem()
    }
    

    用反射修改一个对象的值

    这里遇到了一个小坑,那就是当对象没有暴露出来的时候(首字母没有大写),会失败,出现这个错误 panic: reflect: reflect.Value.SetInt using value obtained using unexported field

    type Geek struct {
        A int `tag1:"First Tag" tag2:"Second Tag"`
        B string
    }
    
    f := Geek{A: 10, B: "Number"}
    fmt.Println(f)
    // {10 Number}
    
    // 必须传址,传值无法修改
    fval := reflect.ValueOf(&f)
    
    // 如果没有Elem()的话,会panic: reflect: call of reflect.Value.Field on ptr Value
    fval.Elem().Field(0).SetInt(14)
    fval.Elem().Field(1).SetString("fads")
    fmt.Println(f)
    // {14 fads}
    

    New()

    有点等同于reflect.ValueOf(&value)但是用法不一样。
    要传入一个reflect.Type,构建出一个新的对象,可以set值进去。
    example

    type Geek struct {
        A int `tag1:"First Tag" tag2:"Second Tag"`
        B string
    }
    
    f := Geek{A: 10, B: "Number"}
    
    // 拿到 Type
    fType := reflect.TypeOf(f)
    // 创建新对象
    fVal := reflect.New(fType)
    // 可以设置值
    fVal.Elem().Field(0).SetInt(20)
    fVal.Elem().Field(1).SetString("Number")
    

    Addr()

    拿到被反射对象的地址,一般是用 .Addr().Interface() 这样用的

    f := Geek{A: 10, B: "Number"}
    fmt.Println(uintptr(unsafe.Pointer(&f)))
    // 824634400800
    fval := reflect.ValueOf(&f).Elem()
    s := fval.Addr().Pointer()
    // 824634400800
    k := fval.Addr().Interface()
    fmt.Println(s == &f)
    // true
    

    相关文章

      网友评论

          本文标题:Golang 反射个人理解

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