reflect反射
1.使用场景
当一些类型未知,有多种类型需要统一处理时,考虑使用反射来做多种情况的统一判断处理。
反射读取数据:
reflect常见类型
reflect.Int,reflect.Int8,reflect.Int16,reflect.Int32,reflect.Int64
reflect.Uint,reflect.Uint8,reflect.Uint16,reflect.Uint32,reflect.Uint64,reflect.Uintptr
reflect.Bool
reflect.String
reflect.Chan,reflect.Func,reflect.Ptr,reflect.Slice,reflect.Map,reflect.Array,reflect.Struct:
reflect.Invalid
reflect.Interface
reflect.TypeOf()
将一个具体的值,转为接口类型!返回具体的类型。
- Type类型
注意格式输出时控制符
t:=reflect.TypeOf(3)
fmt.Println(t.String())
fmt.Printf("%s\n",t.String())
fmt.Printf("%v\n",t)
- Value类型
x := 4
v := reflect.ValueOf(x) //反射拿到Value类型
fmt.Println(v) //4
t := v.Type() //Value实现了各种方法
fmt.Println(t.String()) //int
v := reflect.ValueOf(3) //拿到Value类型到数据值,类型为Value
fmt.Println(v) //3
fmt.Printf("%T", v) //reflect.Value
fmt.Println(v.Int()) //将Value类型转换成特定类型 //3
x := v.Interface() //将Value转成接口类型
i := x.(int)
fmt.Printf("%T\n", i)
m, ok := x.(int) //类型断言,取出其值 ,并转成断言的类型
if !ok {
fmt.Println("类型转换错误")
}
fmt.Printf("%d,%T", m, m) //3,int
- value.Kind()只关心底层表示
var value interface{}
fmt.Println(reflect.ValueOf(value).Kind()) //slice
fmt.Println(reflect.TypeOf(value)) //[]int
反射修改数据
我们可以通过调用reflect.ValueOf(&x).Elem(),来获取任意变量x对应的可取地址的Value。
x := 2
d := reflect.ValueOf(&x).Elem() // d refers to the variable x
px := d.Addr().Interface().(*int) // px := &x
*px = 3 // x = 3
fmt.Println(x) // "3"
慎用反射
- 1.反射代码比较脆弱,不会在构建时报错,只有在真正运行的时候才会抛出Panic
- 难读不易懂,不能做静态类型检查
- 反射代码运行速度慢
Example
将Value类型转成interface
if _, ok := req.(reflect.Value); ok {
req = req.(reflect.Value).Interface()
}
判断比对interface类型:
var req interface{}
switch req.(type) {
case int:
fmt.Println("*")
}
网友评论