反射操作常用函数和方法
func (v Value) Elem() Value
Elem返回v持有的接口保管的值的Value封装,或者v持有的指针指向的值的Value封装。如果v的Kind不是Interface或Ptr会panic;如果v持有的值为nil,会返回Value零值。
func (v Value) SetInt(x int64)
设置v的持有值。如果v的Kind不是Int、Int8、Int16、Int32、Int64之一或者v.CanSet()返回假,会panic。
func (v Value) Int() int64
返回v持有的有符号整数(表示为int64),如果v的Kind不是Int、Int8、Int16、Int32、Int64会panic
func (v Value) Kind() Kind
Kind返回v持有的值的分类,如果v是Value零值,返回值为Invalid
func (v Value) NumField() int
返回v持有的结构体类型值的字段数,如果v的Kind不是Struct会panic
func (v Value) Field(i int) Value
返回结构体的第i个字段(的Value封装)。如果v的Kind不是Struct或i出界会panic
func (v Value) SetString(x string)
设置v的持有值。如果v的Kind不是String或者v.CanSet()返回假,会panic。
func (v Value) NumMethod() int
返回v持有值的方法集的方法数目。
func (v Value) MethodByName(name string) Value
返回v的名为name的方法的已绑定(到v的持有值的)状态的函数形式的Value封装。返回值调用Call方法时不应包含接收者;返回值持有的函数总是使用v的持有者作为接收者(即第一个参数)。如果未找到该方法,会返回一个Value零值。
func (v Value) Call(in []Value) []Value
Call方法使用输入的参数in调用v持有的函数。例如,如果len(in) == 3,v.Call(in)代表调用v(in[0], in[1], in[2])(其中Value值表示其持有值)。如果v的Kind不是Func会panic。它返回函数所有输出结果的Value封装的切片。和go代码一样,每一个输入实参的持有值都必须可以直接赋值给函数对应输入参数的类型。如果v持有值是可变参数函数,Call方法会自行创建一个代表可变参数的切片,将对应可变参数的值都拷贝到里面。
func (v Value) Type() Type
返回v持有的值的类型的Type表示。
反射操作应用
一、通过反射操作基本类型,来改变基本类型的值。
package main import ( "fmt" "reflect" ) func main() { var a int = 1 a = 100 val := reflect.ValueOf(&a) val.Elem().SetInt(200) b := val.Elem().Int() fmt.Printf("a => %d , b => %dn", a, b) }
运行结果:
a => 200 , b => 200
二、反射操作结构体及调用结构体方法。
package main import ( "fmt" "reflect" ) type School struct { Name string Course string } func (s School) Echo() { fmt.Printf("name : %s , Course : %s n", s.Name, s.Course) } func main() { o := School{ Name: "oldboy", Course: "Linux", } val := reflect.ValueOf(&o) kd := val.Kind() if kd != reflect.Ptr && val.Elem().Kind() == reflect.Struct { fmt.Println("expect struct") return } //获取字段数量 fields := val.Elem().NumField() fmt.Printf("struct has %d fieldn", fields) //获取字段的类型 for i := 0; i < fields; i++ { fmt.Printf("%d %vn", i, val.Elem().Field(i).Kind()) } // 操作结构体 val.Elem().Field(1).SetString("Golang") //获取方法数量 methods := val.NumMethod() fmt.Printf("struct has %d methodsn", methods) //反射调用的Echo方法 var params []reflect.Value val.Elem().Method(0).Call(params) }
运行结果:
struct has 2 field 0 string 1 string struct has 1 methods name : oldboy , Course : Golang
反射综合应用
1、定义一个结构体
2、给结构体赋值
3、用反射获取结构体的下标、结构体名称、类型、值
4、改变结构体的值
package main import ( "fmt" "reflect" ) type Student struct { Name string Age int } func main() { u := Student{"oldboy", 18} v := reflect.ValueOf(&u).Elem() t := v.Type() for i := 0; i < v.NumField(); i++ { f := v.Field(i) fmt.Printf("构体的下标: %d: 名称: %s 类型: %s 值: %vn", i, t.Field(i).Name, f.Type(), f.Interface()) } v.Field(0).SetString("老男孩") v.Field(1).SetInt(100) fmt.Println("u is now", u) }
特别声明:以上文章内容仅代表作者本人观点,不代表变化吧观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与变化吧联系。
- 赞助本站
- 微信扫一扫
-
- 加入Q群
- QQ扫一扫
-
评论