1、反射:可以在运行时动态获取变量的相关信息
Import(“reflect”)
两个函数:
reflect.TypeOf()//获取变量的类型,返回reflect.Type类型
reflect.ValueOf()//获取变量的值,返回reflect.Value类型
reflect.Value.Kind()//获取变量的类别,返回一个常量
reflect.Value.Interface()//转换成interface{}类型
可逆状态
示例用法
package main
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
Score float32
}
func test(b interface{}) {
t := reflect.TypeOf(b)
fmt.Println(t)
v := reflect.ValueOf(b)
k := v.Kind()
fmt.Println(k)
iv := v.Interface()
stu, ok := iv.(Student)
if ok {
fmt.Printf("%v %T\n", stu, stu)
}
}
func testInt(b interface{}) {
val := reflect.ValueOf(b)
c := val.Int()
fmt.Printf("get value interface{} %d\n", c)
}
func main() {
var a Student = Student{
Name: "stu01",
Age: 18,
Score: 92,
}
test(a)
testInt(1234)
}
package main
import (
"fmt"
"reflect"
)
func main(){
var x float64=3.4
fmt.Println("type:",reflect.TypeOf(x))
v:=reflect.ValueOf(x)
fmt.Println("value:",v)
fmt.Println("type:",v.Type())
fmt.Println("kind:",v.Kind())
fmt.Println("value:",v.Float())
fmt.Println(v.Interface())
fmt.Printf("value is %5.2e\n",v.Interface())
y:=v.Interface().(float64)
fmt.Println(y)
}
获取变量的值
reflect.ValueOf(x).Float()
reflect.ValueOf(x).Int()
reflect.ValueOf(x).String()
reflect.ValueOf(x).Bool()
反射之elem()修改指针的方法
package main
//通过反射动态修改变量的值
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
Score float32
}
func test(b interface{}) {
t := reflect.TypeOf(b)
fmt.Println(t)
v := reflect.ValueOf(b)
k := v.Kind()
fmt.Println(k)
iv := v.Interface()
stu, ok := iv.(Student)
if ok {
fmt.Printf("%v %T\n", stu, stu)
}
}
func testInt(b interface{}) {
val := reflect.ValueOf(b)
val.Elem().SetInt(100) //val.Elem().Setint()相当于指针操作
c := val.Elem().Int()
fmt.Printf("get value interface{}%d\n", c)
fmt.Printf("string val:%d\n", val.Elem().Int())
}
func main() {
var a Student = Student{
Name: "stu01",
Age: 18,
Score: 92,
}
test(a)
var b int = 1
b = 200
testInt(&b)
fmt.Println(b)
}
用反射操作结构体
reflect.Value.NumField()获取结构体中字段的个数
reflect.Value.Method(n).Call来条用结构体中的方法
反射取得结构体方法个数,字段数
package main
//通过反射动态修改变量的值
import (
"fmt"
"reflect"
)
type Student struct {
Name string
Age int
Score float32
Sex string
}
func (s Student) Set(name string, age int, score float32, sex string) {
s.Name = name
s.Age = age
s.Score = score
s.Sex = sex
}
func TestStruct(a interface{}) {
val := reflect.ValueOf(a)
kd := val.Kind()
if kd != reflect.Struct {
fmt.Println("expect struct")
return
}
num := val.NumField()
fmt.Printf("struct has %d fields\n", num)
numOfMethod := val.NumMethod()
fmt.Printf("struct has %d methods\n", numOfMethod)
}
func main() {
var a Student
a = Student{
Name: "stu01",
Age: 18,
Score: 92.8,
}
TestStruct(a)
fmt.Println(a)
}
反射练习
package main
//通过反射动态修改变量的值
import (
"fmt"
"reflect"
)
type NotKnownType struct {
s1 string
s2 string
s3 string
}
//定义一个String方法
func (n NotKnownType) String() string {
return n.s1 + "-" + n.s2 + "-" + n.s3
}
var secret interface{} = NotKnownType{"Ada", "Go", "Oberon"}
func main() {
value := reflect.ValueOf(secret) //<main.NotKnownType Value>
typ := reflect.TypeOf(secret) //main.NotKnownType
fmt.Println(typ)
knd := value.Kind() //struct
fmt.Println(knd)
for i := 0; i < value.NumField(); i++ {
fmt.Printf("Field %d:%v\n", i, value.Field(i))
}
results := value.Method(0).Call(nil)
fmt.Println(results)//[Ada-Go-Oberon]
}
通过反射修改结构体
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
}
func main() {
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d:%s %s=%v\n",
i, typeOfT.Field(i).Name, f.Type(), f.Interface())
}
s.Field(0).SetInt(77)
s.Field(1).SetString("Sunset Strip")
fmt.Println("t is now", t)
}