反射与文件reflect反射基本概念文件操作反射修改变量压缩归档文件操作01.03.02.04.目录01reflect反射基本概念•反射定义•Type•Value1reflect反射基本概念反射是指在程序运行期间对程序本身进行访问和修改的能力。一般地,程序在编译时,变量会被转换为内存地址,但变量名不会被编译器写入到可执行部分。因此在运行程序时,程序无法获取自身的信息。支持反射的语言则可以在程序编译期将变量的反射信息,如字段名称、类型信息、结构体信息等整合到可执行文件中,并给程序提供接口访问反射信息,这样就可以在程序运行期获取类型的反射信息,并且有能力修改它们。Go语言提供了一种机制在运行时更新和检查变量的值、调用变量的方法和变量支持的内在操作,但是在编译时并不知道这些变量的具体类型,这种机制被称为反射。反射也可以让我们将类型本身作为第一类的值类型处理。Go程序在运行期使用reflect包访问程序的反射信息;主要涉及到Type和Value这两个基本概念。反射定义1reflect反射基本概念reflect.TypeOf(varname).Kind()反射获取变量类型的详细信息reflect.TypeOf(varname).Kind()==reflect.Type反射类型详细信息和基本类型比较注:reflect.Type的Type表示数据变量类型,比如int、float64、string等。reflect.TypeOf(varname)反射获取变量类型packagemainimport("fmt""reflect")funcmain(){varaintfmt.Println(reflect.TypeOf(a).Name())fmt.Println(reflect.TypeOf(a).Kind())fmt.Println(reflect.TypeOf(a).Align())fmt.Println(reflect.TypeOf(a).Kind()==reflect.Float32)}运行结果为:intint8false1reflect反射基本概念reflect.ValueOf(&varname)反射获取指向变量的指针注:&varname表示传入变量地址。需要注意的是,Go语言中不能直接对指针进行运算符或者修改操作,因此通常会使用Elem()函数获取指针指向的值,方便后续对该值进行操作。reflect.ValueOf(varname)反射获取变量值packagemainimport("fmt""reflect")funcmain(){varainta=10fmt.Println(reflect.ValueOf(a))fmt.Println(reflect.ValueOf(&a))fmt.Println(reflect.ValueOf(&a).Elem())}运行结果为:100xc00000a09810reflect.ValueOf(&varname).Elem()反射获取指针地址所指向的值1reflect反射基本概念packagemainimport("fmt""reflect")typePersonstruct{NamestringAgeint}funcmain(){p:=&Person{Name:"Go",Age:20,}fmt.Println(reflect.ValueOf(&p))fmt.Println(reflect.ValueOf(p).Elem())fmt.Println(reflect.ValueOf(p).Type())fmt.Println(reflect.ValueOf(p).Kind())fmt.Println(reflect.TypeOf(p))fmt.Println(reflect.TypeOf(p).Elem())fmt.Println(reflect.TypeOf(p).Name())fmt.Println(reflect.TypeOf(p).Kind())fmt.Println(reflect.TypeOf(p).Size())}运行结果为:0xc000006028{Go20}*main.Personptr*main.Personmain.Personptr802反射修改变量•反射修改变量•反射修改切片•反射修改切片索引值2反射修改变量在使用reflect.ValueOf()的Elem()函数时,如果ValueOf()传入的是变量的地址,那么就可以通过反射去修改变量的值。注:SetType()中的Type表示具体的数据类型,比如SetString()、SetInt()等。reflect.ValueOf(&x).Elem().Set()反射修改变量reflect.ValueOf(&x).Elem().SetType()反射修改变量类型packagemainimport("fmt""reflect")funcmain(){varainta=10varbint=5reflect.ValueOf(&a).Elem().Set(reflect.ValueOf(b))fmt.Println(a)reflect.ValueOf(&a).Elem().SetInt(20)fmt.Println(a)}运行结果为:5202反射修改变量intSliceElemValue:=reflect.ValueOf(&intSlice).Elem()newValue:=reflect.ValueOf(newSliceValue)intSliceElemValue.Set(newValue)反射修改整个切片注:首先使用reflect.ValueOf传入要修改的切片的地址,并且使用Elem获取指针信息;接着使用reflect.ValueOf传入一个新的切片;最后使用Set方法传入新的切片的Value信息,完成对原切片值的修改。intSliceValue:=reflect.ValueOf(intSlice)e:=intSliceValue.Index(index_size)e.SetInt(newvarname)反射修改切片索引值注:在Go...