删除文章

确定要删除这篇文章吗?

取消
确定

go反射

     阅读(60)  2020-02-23 23:54:23

简单结构

package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Id   int
    Name string
    Age  int
}

func (u User) Say() {
    fmt.Println("hello, world!")
}

func PrintInfo(o interface{}) {
    t := reflect.TypeOf(o)
    fmt.Println("Type:", t.Name())

    if kind := t.Kind(); kind != reflect.Struct {
        fmt.Println("Not reflect struct!!!")
        return
    }

    v := reflect.ValueOf(o)
    fmt.Println("Fields:")
    for i := 0; i < t.NumField(); i++ {
        f := t.Field(i)
        val := v.Field(i).Interface()
        fmt.Printf("%s\t: %v = %v\n", f.Name, f.Type, val)
    }

    fmt.Println("Method:")
    for i := 0; i < t.NumMethod(); i++ {
        m := t.Method(i)
        fmt.Printf("%s\t: %v\n", m.Name, m.Type)
        fmt.Printf("execute function: ")
        v.Method(i).Call(nil)
    }
}

func ModifyName(o interface{}, newName string) {
    v := reflect.ValueOf(o)
    if v.Kind() != reflect.Ptr {
        fmt.Println("is not pointer")
        return
    }

    if !v.Elem().CanSet() {
        fmt.Println("cannot set")
        return
    }

    v = v.Elem()
    f := v.FieldByName("Name")
    if !f.IsValid() {
        fmt.Println("name not found")
        return
    }

    if f.Kind() != reflect.String {
        fmt.Println("name is not string")
        return
    }

    f.SetString(newName)
}

func main() {
    user := User{123, "god", 33}
    PrintInfo(user)
    ModifyName(&user, "kelly")
    fmt.Println("new user info:", user)
}

输出:

Type: User
Fields:
Id  : int = 123
Name    : string = god
Age : int = 33
Method:
Say : func(main.User)
execute function: hello, world!
new user info: {123 kelly 33}

复杂结构

package main

import (
    "fmt"
    "reflect"
)

type User struct {
    Id   int
    Name string
    Age  int
}

func (u User) Say() {
    fmt.Println("hello, world!")
}

type Student struct {
    User
    Score int
}

func main() {
    user := User{123, "god", 15}
    student := Student{User: user, Score: 100}
    fmt.Println("student info:", student)

    t := reflect.TypeOf(student)
    fmt.Println("user name type:", t.FieldByIndex([]int{0, 1}))

    v := reflect.ValueOf(student)
    fmt.Println("user name value:", v.FieldByIndex([]int{0, 1}).Interface())
}

输出:

student info: {{123 god 15} 100}
user name type: {Name  string  8 [1] false}
user name value: god

[]int{0, 1}表示Student第0个元素是user,user的第1个元素是Name

修改变量

    i := 100
    v := reflect.ValueOf(&i)
    v.Elem().SetInt(99)
    fmt.Println(i)

输出:99

文章评论

Keep it simple,stupid
文章数
309
总访问量
690952
今日访问
945
最近评论

liangzi : 不错 谢谢分享
tujiaw : registerThreadInactive:如果当前没有激活的线程,就去激活线程,让等待的线程去执行任务。
hgzzx : 佩服佩服。 请教:registerThreadInactive的作用是什么?
xuehaoyun : 很不错,来围观一下
tujiaw : 抱歉csdn code服务关闭了,这个代码我也找不到了
于淞 : 你好,这个文章的源码能分享一下吗,songsong9181@163.com,谢谢了 上面的写错了
于淞 : 你好,这个文章的源码能分享一下吗,838106303@163.com,谢谢了 上面的链接不能用了
tujiaw : 多谢多谢
essaypinglun college-paper.org : 很好的博客,赞赞
Folly : 这个实现有点奇怪,Qt为什么没有统一的比对方法。
回到顶部