下面通过修改int值的例子,学习type Value,以及提供的方法Elem(),这个方法就相当于提供了指针,并指向了这个变量,就可以修改值了。
利用反射操作Int,比如说修改int的值
package main
import (
"fmt"
"reflect"
)
//利用反射,修改值,提供了Elem(),这个方法,相当于一个指针指向变量
func TestInt(b interface{}) {
val := reflect.ValueOf(b) //返回Value这个类型,接下来很多方法可以分析
val.Elem().SetInt(100) //elem这个方法相当于指针指向变量,得到指针指向的变量,才可以操作
c := val.Elem().Int()
fmt.Printf("get value interface{} %d \n", c)
fmt.Printf("string val:%d \n", val.Elem().Int())
}
func main() {
var cc int = 1
TestInt(&cc)
fmt.Println(cc)
}
利用反射查看一个结构体相关信息:比如有多少fileds,有多少method,同时,调用方法的方式。
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
score float32
}
//因为是*Student,method不会统计指针的这个方法
func (s *Student) SetPointer() {
}
//下面两个接受者是值,所以统计method时候有效
func (s Student) SetValue1() {
fmt.Println("----------start-------------")
fmt.Println("SetValue1")
fmt.Println("----------end---------------")
}
func (s Student) SetValue2() {
fmt.Println("----------start-------------")
fmt.Println("SetValue2")
fmt.Println("----------end---------------")
}
func TestStruct(a interface{}) {
val := reflect.ValueOf(a)
if kd := val.Kind(); kd != reflect.Struct {
fmt.Println("unexpect struct", kd)
return
}
num := val.NumField()
fmt.Printf("struct has %d fields \n", num)
numOfMethod := val.NumMethod()
fmt.Printf("struct has %d methods \n", numOfMethod)
//用反射调用结构体的方法
var params []reflect.Value
val.Method(0).Call(params)
val.Method(1).Call(params)
}
func main() {
var a Student = Student{
Name: "stu1",
Age: 18,
score: 99,
}
TestStruct(a)
//传入一个int测试
var b int
TestStruct(b)
}
运行结果:
PS F:\go\src\go_dev> .\main.exe
struct has 3 fields
struct has 2 methods
----------start-------------
SetValue1
----------end---------------
----------start-------------
SetValue1
----------end---------------
unexpect struct int
PS F:\go\src\go_dev>