最新消息: USBMI致力于为网友们分享Windows、安卓、IOS等主流手机系统相关的资讯以及评测、同时提供相关教程、应用、软件下载等服务。

Go语言~反射

维修 admin 46浏览 0评论

Go语言~反射

reflect包

  • type name和type kind
  • ValueOf
  • 通过反射获取值
  • 通过反射设置变量的值
package mainimport ("fmt""reflect"
)func reflectType(x interface{}) {obj := reflect.TypeOf(x)fmt.Println(obj, obj.Name(), obj.Kind())fmt.Printf("obj type of %T\n", obj)
}func reflectValue(x interface{}) {v := reflect.ValueOf(x)fmt.Printf("value is a %v, type is a %T\n", v, v)// 如何得到一个传入时候类型的变量k := v.Kind() // 拿到值对应的类型种类switch k {case reflect.Float32:ret := float32(v.Float())fmt.Printf("value is a %v, type is a %T\n", ret, ret)case reflect.Int32:ret := int32(v.Int())fmt.Printf("value is a %v, type is a %T\n", ret, ret)}
}func reflectSetValue(x interface{}) {v := reflect.ValueOf(x)// Elem()用来根据指针取对应的值k := v.Elem().Kind()switch k {case reflect.Int32:v.Elem().SetInt(100)case reflect.Float32:v.Elem().SetFloat(5.678)}
}type Cat struct{}type Dog struct{}func main() {/*var a float32 = 3.1415926reflectType(a)var b int8 = 10reflectType(b)// 结构体类型var c CatreflectType(c)var d DogreflectType(d)// slicevar e []stringreflectType(e)var f []intreflectType(f)*/// valueOf/*var aa int32 = 100reflectValue(aa)var bb float32 = 3.1415926reflectValue(bb)*/// setValuevar cc int32 = 10reflectSetValue(&cc)fmt.Println(cc)
}

isNil()和isValid()

package main// IsNil()常被用于判断指针是否为空;IsValid()常被用于判定返回值是否有效。import ("fmt""reflect"
)type StructField struct {// Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""Name      stringPkgPath   stringType      reflect.TypeTag       reflect.StructTagOffset    uintptrIndex     []intAnonymous bool
}func main() {// *int类型空指针var a *intfmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil())// nil值fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid())// 实例化一个匿名结构体b := struct{}{}// 尝试从结构体中查找"abc"字段fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid())// 尝试从结构体中查找"abc"方法fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid())// mapc := map[string]int{}// 尝试从map中查找一个不存在的键fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid())
}

结构体反射

package mainimport ("fmt""reflect"
)// 结构体反射type student struct {Name  string `json:"name" ini:"s_name"`Score int    `json:"score" ini:"s_score"`
}// 给student添加两个方法 Study和Sleep(注意首字母大写)
func (s student) Study() string {msg := "好好学习,天天向上。"fmt.Println(msg)return msg
}func (s student) Sleep() string {msg := "好好睡觉,快快长大。"fmt.Println(msg)return msg
}// 根据反射获取结构体中方法的函数
func printMethod(x interface{}) {t := reflect.TypeOf(x)fmt.Println(t.NumMethod())v := reflect.ValueOf(x)// 因为下面需要拿到具体的方法去调用,所以使用的是值信息for i := 0; i < v.NumMethod(); i++ {methodType := v.Method(i).Type()fmt.Printf("method name:%s\n", t.Method(i).Name)fmt.Printf("method:%s\n", methodType)// 通过反射调用方法传递的参数必须是 []reflect.Value 类型var args = []reflect.Value{}v.Method(i).Call(args) // 调用方法}// 通过方法名获取结构体的方法// t.MethodByName("Sleep") // reflect.Method, boolmethodObj := v.MethodByName("Sleep") // reflect.Valuefmt.Println(methodObj.Type())
}func main() {stu1 := student{Name:  "枫林神",Score: 90,}/*// 通过反射区获取结构体中的所有字段信息t := reflect.TypeOf(stu1)fmt.Printf("name :%v kind :%v\n", t.Name(), t.Kind())// 遍历结构体变量的所有字段for i := 0; i < t.NumField(); i++ {//根据结构体字段的索引取字段filedobj := t.Field(i)fmt.Printf("name:%v type:%v tag:%v\n", filedobj.Name, filedobj.Type, filedobj.Tag)fmt.Println(filedobj.Tag.Get("json"), filedobj.Tag.Get("ini"))}// 根据名字取结构体中的字段filedobj2, ok := t.FieldByName("Score")if ok {fmt.Printf("name:%v type:%v tag:%v\n", filedobj2.Name, filedobj2.Type, filedobj2.Tag)}*/printMethod(stu1)
}

Go语言~反射

reflect包

  • type name和type kind
  • ValueOf
  • 通过反射获取值
  • 通过反射设置变量的值
package mainimport ("fmt""reflect"
)func reflectType(x interface{}) {obj := reflect.TypeOf(x)fmt.Println(obj, obj.Name(), obj.Kind())fmt.Printf("obj type of %T\n", obj)
}func reflectValue(x interface{}) {v := reflect.ValueOf(x)fmt.Printf("value is a %v, type is a %T\n", v, v)// 如何得到一个传入时候类型的变量k := v.Kind() // 拿到值对应的类型种类switch k {case reflect.Float32:ret := float32(v.Float())fmt.Printf("value is a %v, type is a %T\n", ret, ret)case reflect.Int32:ret := int32(v.Int())fmt.Printf("value is a %v, type is a %T\n", ret, ret)}
}func reflectSetValue(x interface{}) {v := reflect.ValueOf(x)// Elem()用来根据指针取对应的值k := v.Elem().Kind()switch k {case reflect.Int32:v.Elem().SetInt(100)case reflect.Float32:v.Elem().SetFloat(5.678)}
}type Cat struct{}type Dog struct{}func main() {/*var a float32 = 3.1415926reflectType(a)var b int8 = 10reflectType(b)// 结构体类型var c CatreflectType(c)var d DogreflectType(d)// slicevar e []stringreflectType(e)var f []intreflectType(f)*/// valueOf/*var aa int32 = 100reflectValue(aa)var bb float32 = 3.1415926reflectValue(bb)*/// setValuevar cc int32 = 10reflectSetValue(&cc)fmt.Println(cc)
}

isNil()和isValid()

package main// IsNil()常被用于判断指针是否为空;IsValid()常被用于判定返回值是否有效。import ("fmt""reflect"
)type StructField struct {// Name是字段的名字。PkgPath是非导出字段的包路径,对导出字段该字段为""Name      stringPkgPath   stringType      reflect.TypeTag       reflect.StructTagOffset    uintptrIndex     []intAnonymous bool
}func main() {// *int类型空指针var a *intfmt.Println("var a *int IsNil:", reflect.ValueOf(a).IsNil())// nil值fmt.Println("nil IsValid:", reflect.ValueOf(nil).IsValid())// 实例化一个匿名结构体b := struct{}{}// 尝试从结构体中查找"abc"字段fmt.Println("不存在的结构体成员:", reflect.ValueOf(b).FieldByName("abc").IsValid())// 尝试从结构体中查找"abc"方法fmt.Println("不存在的结构体方法:", reflect.ValueOf(b).MethodByName("abc").IsValid())// mapc := map[string]int{}// 尝试从map中查找一个不存在的键fmt.Println("map中不存在的键:", reflect.ValueOf(c).MapIndex(reflect.ValueOf("娜扎")).IsValid())
}

结构体反射

package mainimport ("fmt""reflect"
)// 结构体反射type student struct {Name  string `json:"name" ini:"s_name"`Score int    `json:"score" ini:"s_score"`
}// 给student添加两个方法 Study和Sleep(注意首字母大写)
func (s student) Study() string {msg := "好好学习,天天向上。"fmt.Println(msg)return msg
}func (s student) Sleep() string {msg := "好好睡觉,快快长大。"fmt.Println(msg)return msg
}// 根据反射获取结构体中方法的函数
func printMethod(x interface{}) {t := reflect.TypeOf(x)fmt.Println(t.NumMethod())v := reflect.ValueOf(x)// 因为下面需要拿到具体的方法去调用,所以使用的是值信息for i := 0; i < v.NumMethod(); i++ {methodType := v.Method(i).Type()fmt.Printf("method name:%s\n", t.Method(i).Name)fmt.Printf("method:%s\n", methodType)// 通过反射调用方法传递的参数必须是 []reflect.Value 类型var args = []reflect.Value{}v.Method(i).Call(args) // 调用方法}// 通过方法名获取结构体的方法// t.MethodByName("Sleep") // reflect.Method, boolmethodObj := v.MethodByName("Sleep") // reflect.Valuefmt.Println(methodObj.Type())
}func main() {stu1 := student{Name:  "枫林神",Score: 90,}/*// 通过反射区获取结构体中的所有字段信息t := reflect.TypeOf(stu1)fmt.Printf("name :%v kind :%v\n", t.Name(), t.Kind())// 遍历结构体变量的所有字段for i := 0; i < t.NumField(); i++ {//根据结构体字段的索引取字段filedobj := t.Field(i)fmt.Printf("name:%v type:%v tag:%v\n", filedobj.Name, filedobj.Type, filedobj.Tag)fmt.Println(filedobj.Tag.Get("json"), filedobj.Tag.Get("ini"))}// 根据名字取结构体中的字段filedobj2, ok := t.FieldByName("Score")if ok {fmt.Printf("name:%v type:%v tag:%v\n", filedobj2.Name, filedobj2.Type, filedobj2.Tag)}*/printMethod(stu1)
}

与本文相关的文章

发布评论

评论列表 (0)

  1. 暂无评论