Golang Reflex Reflection

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Reflective Reflection

    • Reflection can greatly increase the flexibility of the program, so that interface{} has a greater scope of play
    • Reflection uses the TypeOf and valueof functions to get target object information from the interface
    • Reflection will use anonymous fields as separate fields (anonymous field nature)
    • You want to use reflection to modify the state of an object, if Interface.data is settable, which is pointer-interface
    • The method can be called "dynamic" by reflection

Basic operation of reflection on a struct

package mainimport (    "fmt"    "reflect")type User struct {    Id   int    Name string    Age  int}func (u User) Hello() {    fmt.Println("Hello world!")}func Info(o interface{}) {    t := reflect.TypeOf(o)         //反射使用 TypeOf 和 ValueOf 函数从接口中获取目标对象信息    fmt.Println("Type:", t.Name()) //调用t.Name方法来获取这个类型的名称    v := reflect.ValueOf(o) //打印出所包含的字段    fmt.Println("Fields:")    for i := 0; i < t.NumField(); i++ { //通过索引来取得它的所有字段,这里通过t.NumField来获取它多拥有的字段数量,同时来决定循环的次数        f := t.Field(i)               //通过这个i作为它的索引,从0开始来取得它的字段        val := v.Field(i).Interface() //通过interface方法来取出这个字段所对应的值        fmt.Printf("%6s:%v =%v\n", f.Name, f.Type, val)    }    for i := 0; i < t.NumMethod(); i++ { //这里同样通过t.NumMethod来获取它拥有的方法的数量,来决定循环的次数        m := t.Method(i)        fmt.Printf("%6s:%v\n", m.Name, m.Type)    }}func main() {    u := User{1, "Jack", 23}    Info(u)}

Determine if the incoming type is the type we want

Package Mainimport ("FMT" "reflect") type User struct {Id int Name string Age int}func (U User) Hello () {FMT. Println ("Hello world!")} Func Info (o interface{}) {t: = reflect. TypeOf (o)//reflection uses the TypeOf and VALUEOF functions to obtain the target object information from the interface FMT. Println ("Type:", T.name ())//Call T. The name method is used to get the names of this type if k: = T.kind (); K! = reflect. Struct {//The kind method is used to determine if the incoming type is the type FMT we need to reflect. Println ("XX") return} V: = reflect. ValueOf (o)//print out the included fields in FMT. Println ("Fields:") for I: = 0; I < T.numfield (); i++ {//through the index to get all of its fields, here through T. Numfield to get the number of fields it has, and also to determine how many cycles f: = T.field (i)//through this I as its index, starting from 0 to get its field val: = V.field (i). Interface ()//Use the Interface method to remove the value of this field for FMT. Printf ("%6s:%v =%v\n", F.name, F.type, Val)} for I: = 0; I < T.nummethod (); i++ {//here also through T. Nummethod to get the number of methods it has to determine the number of cycles m: = T.method (i) fmt.   Printf ("%6s:%v\n", M.name, M.type)}}func main () {u: = user{1, "Jack", 23} Info (U)} 

Reflect anonymous or embedded fields

package mainimport (    "fmt"    "reflect")type User struct {    Id   int    Name string    Age  int}type Manager struct {    User  //反射会将匿名字段作为一个独立字段来处理    Title string}func main() {    m := Manager{User: User{1, "Jack", 12}, Title: "123"}    t := reflect.TypeOf(m)    fmt.Printf("%#v\n", t.Field(0))                   //#号会将reflect的struct的详情页打印出来,可以看出来这是一个匿名字段    fmt.Printf("%#v \n", t.FieldByIndex([]int{0, 0})) //此时 我们就可以将User当中的ID取出来,这里面需要传进方法中的是一个int类型的slice,User相对于manager索引是0,id相对于User索引也是0    fmt.Printf("%v \n", t.FieldByIndex([]int{0, 1}))    v := reflect.ValueOf(m)    fmt.Printf("%#v\n", v.Field(0))}

Modify the contents of a struct by reflection

package mainimport (    "fmt"    "reflect")func main() {    x := 123    v := reflect.ValueOf(&x)       //传递指针才能修改    v.Elem().SetInt(999)    fmt.Println(x)}PS G:\mygo\src\mytest> go run .\temp10.go999
package mainimport (    "fmt"    "reflect")type User struct {    Id   int    Name string    Age  int}func main() {    u := User{1, "Tom", 12}    Set(&u)    fmt.Println(u)}func Set(o interface{}) {    v := reflect.ValueOf(o)    if v.Kind() == reflect.Ptr && !v.Elem().CanSet() {        fmt.Println("xxx")        return    } else {        v = v.Elem()    }    f := v.FieldByName("Name")    if !f.IsValid() {        fmt.Println("xiugaishibai")    }    if f.Kind() == reflect.String {        f.SetString("jACK")    }}

Invoking methods dynamically by means of the firing method

  Package Mainimport ("FMT" "reflect") type User struct {Id int. Name string Age int}func (U Us ER) Hello (name string) {FMT. Println ("Hello", Name, "My name is", U.name)}func main () {u: = user{1, "OK", "k} V: = reflect. ValueOf (u) MV: = V.methodbyname ("Hello") args: = []reflect. Value{reflect. ValueOf ("JOE")} mv. Call (args)}  

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.