反射:可以在运行时,动态获取变量的信息 ,比如变量的类型,类别
1.对于结构体变量,还可以获取到结构体的字段,方法
2.实现这个功能的是 reflect包
reflect.TypeOf(),获取变量的类型,返回reflect.Type类型
reflect.ValueOf(),获取变量的值,返回reflect.Value类型
reflect.Value.Kind(),获取变量的类别,返回一个常量
reflect.Value.Interface(),转换成interface{}类型
使用反射场景,json序列化
package main
import (
"encoding/json"
"fmt"
)
type Student struct {
Name string `json:"学生名"`
Age int `json:"学生年纪"`
Class string `json:"班级"`
}
func main() {
stu := Student{
"尼古拉斯赵四",
18,
"舞王班",
}
data, err := json.Marshal(stu)
if err != nil {
fmt.Println("序列化出错", err)
}
fmt.Println("json序列化结果:", string(data))
}
反射获取基本类型
package main
import (
"fmt"
"reflect"
)
func main() {
var num int64 = 12345
fmt.Println("num类型", reflect.TypeOf(num))
//获取变量的值
resNum := reflect.ValueOf(num)
fmt.Printf("类型:%T 值:%v\n", resNum, resNum)
fmt.Printf("resNum值:%v\n", resNum)
fmt.Printf("resNum类型:%v\n", resNum.Type())
fmt.Printf("resNum种类:%v\n", resNum.Kind())
fmt.Printf("resNum确认值:%v\n", resNum.Int())
}
反射获取结构体
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)
fmt.Println("参数值:", v)
k := v.Kind()
fmt.Println("参数种类:", k)
//转化为接口返回
iv := v.Interface()
fmt.Printf("类型:%T 值:%v\n", iv, iv)
//类型断言,如果这个接口是student类型
stu, ok := iv.(Student)
if ok {
fmt.Printf("结构体值:%v 类型:%T\n", stu, stu)
}
}
func main() {
var a Student = Student{
Name: "周星驰",
Age: 18,
Score: 99,
}
//传入结构体
test(a)
}
反射elem获取指针指向的变量
package main
import (
"fmt"
"reflect"
)
//fv.Elem()用来获取指针指向的变量
func testInt(b interface{}) {
//获取b的类型
val := reflect.ValueOf(b)
fmt.Printf("参数b的类型是:%T 值是:%v\n", val, val)
fmt.Printf("val.Elem()获取到变量的类型:%T 值:%v\n", val.Elem(), val.Elem())
//修改val的值
val.Elem().SetInt(100)
//返回 一个int值类型
c := val.Elem().Int()
fmt.Printf("类型:%T 值是:%d\n", c, c)
}
func main() {
var b int = 1
b = 200
testInt(&b)
fmt.Println("b的值:", b)
}
理解reflect.Value.Elem()
package main
import (
"fmt"
"reflect"
)
func main() {
var num int = 100
//返回变量的值,传入地址,那就是内存地址的值
fn := reflect.ValueOf(&num)
//修改指针指向的值,也就是修改num的值
fn.Elem().SetInt(222)
fmt.Printf("此时num的值:%d\n", num)
//以上操作,等同于
var num2 = 111
var b *int = &num2
*b = 333
fmt.Printf("b的类型:%T\n", b)
fmt.Println(num2)
}
|
请发表评论