首页 > 代码库 > Go - reflection

Go - reflection

Go 语言也有反射的机制,通过这种机制可以大大提高程序的灵活性。

 

reflect包中的 TypeOf 与 ValueOf 方法

首先,当我们想要使用反射技术的时候,我们需要先引用 reflect 包。

import (    "fmt"    "reflect")

之后,我们就可以通过reflect包中的TypeOf方法来取到类型,并且使用ValueOf方法来获取字段及方法。我们来看一个实例

// reflect.gopackage mainimport (    "fmt"    "reflect")type User struct {    Name string    Age  int    Sex  string}func (u User) SayHello() {    fmt.Println("Hello there, I am %s ...", u.Name)}func main() {    user := User{        "Tony",        30,        "male"}    info(user)}func info(o interface{}) {    t := reflect.TypeOf(o)    fmt.Printf("Type is: %s \n", t.Name())    fmt.Printf("Fields are: \n")    // find out fileds    v := reflect.ValueOf(o)    for i := 0; i < t.NumField(); i++ {        f := t.Field(i)        val := v.Field(i).Interface()        fmt.Printf("%6s: %v=%v\n", f.Name, f.Type, val)    }    // find out methods    for i := 0; i < t.NumMethod(); i++ {        m := t.Method(i)        fmt.Printf("%6s: %v\n", m.Name, m.Type)    }}

output:

技术分享

 

 使用反射修改类型

如果我们需要通过反射的方式来修改类型的字段,那么传入给ValueOf()方法的参数应该是对象的引用。

// reflect1.gopackage mainimport (    "fmt"    "reflect")type People struct {    Name string    Age  int}func main() {    p := People{"Tony", 30}    fmt.Printf("my name is: %s\n", p.Name)    val := reflect.ValueOf(&p)    f := val.Elem().FieldByName("Name")    f.SetString("Tom")    fmt.Printf("my name is: %s\n", p.Name)}

 

使用反射来“动态”调用方法

// reflect1.gopackage mainimport (    "fmt"    "reflect")type People struct {    Name string    Age  int}func (p People) Hello(name string) {    fmt.Printf("Hello there, I am %s", name)}func main() {    p := People{"Tony", 30}    v := reflect.ValueOf(p)    mv := v.MethodByName("Hello")    args := []reflect.Value{reflect.ValueOf("Tom")}    mv.Call(args)}

需要注意的是,通过反射调用方法的时候需要以slice的形式传入参数,

 args := []reflect.Value{reflect.ValueOf("Tom")}

 最后使用method.call来调用方法
mv.Call(args)

Go - reflection