美文网首页我爱编程
反射reflection-GOLANG

反射reflection-GOLANG

作者: 与子笑 | 来源:发表于2018-05-20 10:33 被阅读0次

golang  @amazeUI  2017-11-02 11:18:07

type User struct {

    Name string

    Age  int

    Id   int

}

func (u User) GetName(name string) { //将匿名方法绑定到结构体中

    fmt.Println("我的名字叫", u.Name, "传进来的是", name)

}

func main() {

    a := User{"xiaoming", 5, 6}

    a.GetName("测试1")

    Setname(&a)

    a.GetName("测试2")

    fmt.Println(a.Name)

    info(a)

    ra := reflect.ValueOf(a)

    rm := ra.MethodByName("GetName")

    args := []reflect.Value{reflect.ValueOf("测试三")} //通过反射调用该对象方法

    //这里再次回到切片与数组。到底什么是切片,什么是数组

    //再次总结一下,刚看了点资料,以下是链接

    //https://www.zhihu.com/question/66673454

    //以下是总结

    //1.数组要指明长度Array := [ArrayLength] ElementType,arr :=[4]int,数组拷贝为值拷贝

    //2.切片不需要指明长度SliceT := []ElementType,但是他有容量机制,拷贝为指针拷贝

    arr := [4]int{0, 1, 3, 4}

    arrs := arr[1:2]

    ccc := reflect.TypeOf(arrs).Kind() //通过反射判断是一个数组还是切片

    fmt.Println(ccc)

    rm.Call(args)

}

func info(o interface{}) { //获取这个实例化了的结构体的所有信息

    ot := reflect.TypeOf(o)  //通过反射获取类型

    ov := reflect.ValueOf(o) //获取值

    fmt.Println(ot, "\n")

    fmt.Println(ov, "\n")

    fmt.Println(ot.Name(), "\n")            //打印这个实现了空接口的结构名称

    for i := 0; i < ot.NumField(); i += 1 { //获取这个结构体内的值

        n := ot.Field(i)

        val := ov.Field(i)

        fmt.Println(n.Type, ":", n.Name, ",", val)

    }

    for i := 0; i < ot.NumMethod(); i += 1 { //打印这个结构体的每个方法

        f := ot.Method(i)

        fmt.Printf("%s:%v,%v\n", f.Name, f.Type, f.Index)

    }

}

func Setname(o interface{}) { //通过反射设置值

    v := reflect.ValueOf(o)

    fmt.Println(v.Elem())          //这里打印出来是这个结构体

    fmt.Println(v.Elem().CanSet()) //这里返回的是个布尔

    fmt.Println(v.Kind())          //这里打印出来的就是ptr

    fmt.Println(reflect.Ptr)       //也是ptr,引出个问题,为什么不用字符串"ptr"?以后再找答案,指针

    fmt.Println(v)

    //Elem返回v持有的接口保管的值的Value封装,

    //或者v持有的指针指向的值的Value封装。如果v的Kind不是Interface或Ptr会panic;如果v持有的值为nil,会返回Value零值。

    //Kind返回v持有的值的分类,如果v是Value零值,返回值为Invalid

    if v.Kind() == reflect.Ptr && !v.Elem().CanSet() { //如果是指针且不能被修改

        fmt.Println("xxx") //这个判断有问题,如果不是指针也会走else,或者可以修改但不是指针也会走else

        return

    } else {

        v = v.Elem()

    }

    n := v.FieldByName("Name")

    if n.IsValid() && n.Kind() == reflect.String { //如果取到了值并且类型是字符串则修改

        fmt.Println(n, "\n", n.Kind())

        n.SetString("lele") //修改名字//通过反射对值进行修改,肯定可以修改拉,传进来的是指针

    }

}

下面是执行结果

我的名字叫 xiaoming 传进来的是 测试1

{xiaoming 5 6}

true

ptr

ptr

&{xiaoming 5 6}

xiaoming

string

我的名字叫 lele 传进来的是 测试2

lele

main.User

{lele 5 6}

User

string : Name , lele

int : Age , 5

int : Id , 6

GetName:func(main.User, string),0

slice

我的名字叫 lele 传进来的是 测试三

成功: 进程退出代码 0.

相关文章

  • 反射 reflection golang

    原文链接:反射reflection-GOLANG

  • 反射reflection-GOLANG

    golang -@amazeUI -2017-11-02 11:18:07 type User struct { ...

  • Java基础之反射

    Java基础之反射 反射基本介绍 反射的使用通过反射调用属性和方法通过反射获取配置文件 反射基本介绍 Java反射...

  • 镜面反射矩阵的推导

    镜面反射是以镜面作为反射平面,实物与反射物到反射平面的距离相等,实物与反射物方向相反,所以,反射矩阵由反射平面确定...

  • reflect.go包学习_之二 指针操作提高反射性能 反射应用

    reflect.go包学习_之二 指针操作提高反射性能 反射应用 反射创建实例 反射信息、反射调用方法、反射修改值...

  • Java互联网公司-经典面试题附答案

    基础:Java 反射?反射有什么缺点?你是怎么理解反射的(为什么框架需要反射)?优点:反射具有解耦性,缺点:反射属...

  • Java反射与joor反射库的使用

    java原生反射的使用 反射构造对象 反射方法 反射字段 joor反射库的使用 github:https://gi...

  • Java反射

    什么是反射? 反射的作用? 反射性能优化?

  • 反射三定律

    反射第一定律:反射可以将interface类型变量转换成反射对象 反射第二定律:反射可以将反射对象还原成inter...

  • 反射

    1.反射是什么?反射的定义,概念 2.为什么要学反射? 3.怎么使用反射?反射的使用

网友评论

    本文标题:反射reflection-GOLANG

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