反射:在运行时动态获取变量的相关信息,导入包:import “reflect”
1.reflect.TypeOf(),获取变量的类型,返回reflect.Type类型。对结构体操作则显示结构体名。
2.reflect.ValueOf(),获取变量的值,返回reflect.Value类型。(赋值,值传递)
3.reflect.Value.Kind(),获取变量的类别,返回一个常量。对结构体操作则显示struct。
4.reflect.Value.Interface(),转换成interface{}类型。
变量↔Interface{}↔Reflect.Value
package main
import (
"fmt"
"reflect"
)
func main() {
var x float64 = 3.4
fmt.Println("type:", reflect.TypeOf(x))
v := reflect.ValueOf(x)
fmt.Println("value:", v)
fmt.Println("type:", v.Type())
fmt.Println("kind:", v.Kind())
fmt.Println("value:", v.Float())
fmt.Println(v.Interface())
fmt.Printf("value is %5.2e\n", v.Interface())
y := v.Interface().(float64)
fmt.Println(y)
}
获取变量的值:
1.reflect.ValueOf(x).Float()
2.reflect.ValueOf(x).Int()
3.reflect.ValueOf(x).String()
4.reflect.ValueOf(x).Bool()
通过反射的来改变变量的值:
reflect.Value.SetXX相关方法,比如:
1.reflect.Value.SetFloat(),设置浮点数
2.reflect.Value.SetInt(),设置整数
3.reflect.Value.SetString(),设置字符串
package main
import (
"fmt"
"reflect"
)
func main() {
var a float64
fv := reflect.ValueOf(&a)
fv.Elem().SetFloat(3.3)
fmt.Printf("%v\n", a)
}
其中fv.Elem()用来获取指针指向的变量,相当于: var a *int; *a = 100
用反射操作结构体:
1.reflect.Value.NumField()获取结构体中字段的个数
2.reflect.Value.Method(n).Call来调用结构体中的方法
package main
import (
"fmt"
"reflect"
)
type NotknownType struct {
s1 string
s2 string
s3 string
}
func (n NotknownType) String() string {
return n.s1 + "-" + n.s2 + "-" + n.s3
}
var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}
func main() {
value := reflect.ValueOf(secret) // <main.NotknownType Value>
typ := reflect.TypeOf(secret) // main.NotknownType
fmt.Println(typ)
knd := value.Kind() // struct
fmt.Println(knd)
for i := 0; i < value.NumField(); i++ {
fmt.Printf("Field %d: %v\n", i, value.Field(i))
//value.Field(i).SetString("C#")
}
results := value.Method(0).Call(nil)
fmt.Println(results) // [Ada - Go - Oberon]
}
package main
import (
"fmt"
"reflect"
)
type T struct {
A int
B string
}
func main() {
t := T{23, "skidoo"}
s := reflect.ValueOf(&t).Elem()
typeOfT := s.Type()
for i := 0; i < s.NumField(); i++ {
f := s.Field(i)
fmt.Printf("%d: %s %s = %v\n", i,
typeOfT.Field(i).Name, f.Type(), f.Interface())
}
s.Field(0).SetInt(77)
s.Field(1).SetString("Sunset Strip")
fmt.Println("t is now", t)
}