定义:
ValueOf用来获取输入参数接口中的数据的值,如果接口为空则返回0
TypeOf用来动态获取输入参数接口中的值的类型,如果接口为空则返回nil
package main
import (
"fmt"
"reflect"
)
func main() {
// 反射操作:通过反射,可以获取一个接口类型变量的 类型和数值
var x float64 = 3.4
fmt.Println("type: ", reflect.TypeOf(x)) // type: float64
fmt.Println("value: ", reflect.ValueOf(x)) // value: 3.4
// 根据反射的值,获取对应的类型和值
v := reflect.ValueOf(x)
fmt.Println("kind is float64: ", v.Kind() == reflect.Float64) // kind is float64: true
fmt.Println("type:", v.Type()) // type: float64
fmt.Println("value:", v.Float()) // value: 3.4
}go类型定义:
- 静态类型
静态类型在编译时都是确定的,例如:int,float32,*int,[]byte,chan []int
// 静态类型
type Myint int
var i *int- 动态类型
运行时给这个变量赋值,这个变量的动态类型,取决与它的赋值类型。前提是这个变量是一个接口类型
// 动态类型
var a interface{} // 静态类型为interface{}
a = 10 // 动态类型为int
a = "abc" // 动态类型为string类型转换:
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
// 接口类型变量 -> 反射类型对象
value := reflect.ValueOf(x)
fmt.Printf("value:%v, type:%T\n", value, value) // value:3.4, type:reflect.Value
// 反射类型对象 -> 接口类型变量,理解为’强制转换‘
convertValue := value.Interface().(float64)
fmt.Printf("value:%v, type:%T\n", convertValue, convertValue) // value:3.4, type:float64
pointer := reflect.ValueOf(&x)
convertPointer := pointer.Interface().(*float64)
fmt.Printf("value:%v, type:%T", convertPointer, convertPointer) // value:0xc000014088, type:*float64
}结构体使用reflect:
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func (p Person) Say(msg string) {
fmt.Println("hello ", msg)
}
func (p Person) PrintInfo() {
fmt.Printf("姓名:%s, 年龄:%d\n", , p.Age)
}
func GetMessage(inp interface{}) {
getType := reflect.TypeOf(inp) // 先获取inp的类型
fmt.Println("get type is: ", ()) // get type is: Person
fmt.Println("get kind is: ", getType.Kind()) // get kind is: struct
getValue := reflect.ValueOf(inp)
fmt.Println("get all Fields is: ", getValue) // get all Fields is: {zhangsa 11}
// 获取每个字段信息
/*
1.先获取Type对象:reflect.Type
NumField()
Field(index)
2.通过Field()获取每一个Field字段
3.interface()获取对应value
*/
for i := 0; i < getType.NumField(); i++ {
field := getType.Field(i)
value := getValue.Field(i).Interface()
fmt.Printf("字段名称:%s, 字段类型:%s, 字段数值:%v\n", , field.Type, value)
// 字段名称:Name, 字段类型:string, 字段数值:zhangsa
// 字段名称:Age, 字段类型:int, 字段数值:11
}
// 直接通过FieldByName获取某个字段名称
name := getValue.FieldByName("Name")
fmt.Println("name: ", name) // name: zhangsa
// 获取方法
for i := 0; i < getType.NumMethod(); i++ {
method := getType.Method(i)
fmt.Printf("方法名称:%s, 方法类型:%v\n", method.Name, method.Type)
// 方法名称:PrintInfo, 方法类型:func(main.Person)
// 方法名称:Say, 方法类型:func(main.Person, string)
}
}
func main() {
p := Person{Name: "zhangsa", Age: 11}
GetMessage(p)
}通过reflect.Value设置实际变量的值:
reflect.Value是通过reflect.ValueOf(x)获得的,只有当x是指针的时候,才可以通过reflect.Value修改实际变量x的值
即:通过refPtrVal := reflect.ValueOf(&var)的方式获取指针类型,然后使用refPtrVal.elem().set(一个新的reflect.Value)来进行更改
package main
import (
"fmt"
"reflect"
)
func main() {
var n float64 = 2.3
fmt.Println("n: ", n) // 2.3
// 获取&n的reflect值对象
pointer := reflect.ValueOf(&n) // 需要操作指针
// 获取原始值(n)对应的反射对象
newValue := pointer.Elem()
fmt.Println("类型:", newValue.Type()) // float64
fmt.Println("是否可以修改数据:", newValue.CanSet()) // true
// 重新赋值
newValue.SetFloat(3.5)
fmt.Println(n) // 3.5
}package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{"zsan", 11}
fmt.Printf("%T\n", p) // main.Person
p2 := &p
fmt.Printf("%T\n", p2) // *main.Person
fmt.Println() // zsan
// 简写
fmt.Println() // zsan
fmt.Println((*p2).Name) // zsan
// 改变数值
value := reflect.ValueOf(&p)
typ := reflect.TypeOf(&p)
fmt.Printf("%v\n", typ.Kind()) // ptr
fmt.Printf("%v\n", value.Kind()) // ptr
if value.Kind() == reflect.Ptr {
newValue := value.Elem()
fmt.Println(newValue.CanSet()) // true
name := newValue.FieldByName("Name")
fmt.Println("name: ", name) // name: zsan
name.SetString("lisi444")
fmt.Println(p) // {lisi444 11}
}
}方法的调用:
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func (p Person) Say(msg string) {
fmt.Println("hello ", msg)
}
func (p Person) PrintInfo() {
fmt.Printf("姓名:%s, 年龄:%d\n", , p.Age)
}
func (p Person) Test(i, j int, m string) {
fmt.Printf("%d%d%s", i, j, m)
}
func main() {
/*
通过反射进行方法的调用
1.接口变量->反射对象(value)
2.获取对应的方法对象:MethodByName()
3.将方法对象进行调用:Call()
*/
p := Person{"zhangsan", 22}
value := reflect.ValueOf(p)
fmt.Printf("kind: %s, type: %s\n", value.Kind(), value.Type()) // kind: struct, type: main.Person
// 调用无参数方法
methodValue1 := value.MethodByName("PrintInfo")
fmt.Printf("kind: %s, type: %s\n", methodValue1.Kind(), methodValue1.Type()) // kind: func, type: func()
// 没有参数时,直接调用,
// 方式1 没有参数,直接写nil
methodValue1.Call(nil) // 姓名:zhangsan, 年龄:22
// 方式2 创建一个空的切片
args1 := make([]reflect.Value, 0)
methodValue1.Call(args1) // 姓名:zhangsan, 年龄:22
// 调用1个参数方法
methodValue2 := value.MethodByName("Say")
fmt.Printf("kind: %s, type: %s\n", methodValue2.Kind(), methodValue2.Type()) // kind: func, type: func(string)
args2 := []reflect.Value{reflect.ValueOf("反射机制传参")}
methodValue2.Call(args2) /// hello 反射机制传参
// 调用多个参数方法
methodValue3 := value.MethodByName("Test")
fmt.Printf("kind: %s, type: %s\n", methodValue3.Kind(), methodValue3.Type()) // kind: func, type: func(int, int, string)
args3 := []reflect.Value{reflect.ValueOf(1), reflect.ValueOf(2), reflect.ValueOf("反射机制传参")}
methodValue3.Call(args3) // 12反射机制传参
}函数的调用:
package main
import (
"fmt"
"reflect"
"strconv"
)
func fun1() {
fmt.Println("我是函数fun1(), 无参数。。")
}
func fun2(i int, s string) {
fmt.Println("我是函数fun2(), 有参数。。")
}
func fun3(i int, s string) string {
fmt.Println("我是函数fun3(), 无参数,也有返回值")
return s + strconv.Itoa(i)
}
func main() {
// 函数的反射
/*
1.函数->反射对象
2.kind->func
3.call()
*/
f1 := fun1
value := reflect.ValueOf(f1)
fmt.Printf("kind: %s, type: %s\n", value.Kind(), value.Type()) // kind: func, type: func()
value2 := reflect.ValueOf(fun2)
fmt.Printf("kind: %s, type: %s\n", value2.Kind(), value2.Type()) // kind: func, type: func(int, string)
value3 := reflect.ValueOf(fun3)
fmt.Printf("kind: %s, type: %s\n", value3.Kind(), value3.Type()) // kind: func, type: func(int, string) string
// 通过反射调用函数
value.Call(nil)
value2.Call([]reflect.Value{reflect.ValueOf(22), reflect.ValueOf("hello")})
result := value3.Call([]reflect.Value{reflect.ValueOf(33), reflect.ValueOf("nihao")})
fmt.Printf("%T\n", result) // []reflect.Value
fmt.Println(len(result)) // 1
fmt.Printf("kind: %s, type: %s\n", result[0].Kind(), result[0].Type()) // kind: string, type: string
s := result[0].Interface().(string)
fmt.Println(s) // nihao33
fmt.Printf("%T\n", s) // string
}
















