反射是用程序检查其所拥有的结构,尤其是类型的一种能力;这是元编程的一种形式。反射可以在运行时检查类型和变量,例如它的大小、方法和 动态
的调用这些方法。这对于没有源代码的包尤其有用。这是一个强大的工具,除非真得有必要,否则应当避免使用或小心使用。
变量的最基本信息就是类型和值:反射包的 Type 用来表示一个 Go 类型,反射包的 Value 为 Go 值提供了反射接口。
两个简单的函数,reflect.TypeOf 和 reflect.ValueOf,返回被检查对象的类型和值。例如,x 被定义为:var x float64 = 3.4,那么 reflect.TypeOf(x) 返回 float64,reflect.ValueOf(x) 返回 <float64 Value>
反射对象示例
package mainimport ("fmt""reflect")type NotknownType struct {s1, s2, s3 string}func (n NotknownType) String() string {return n.s1 + " - " + n.s2 + " - " + n.s3}// variable to investigate:var secret interface{} = NotknownType{"Ada", "Go", "Oberon"}func main() {value := reflect.ValueOf(secret) // <main.NotknownType Value>typ := reflect.TypeOf(secret) // main.NotknownType// alternative://typ := value.Type() // main.NotknownTypefmt.Println(typ)knd := value.Kind() // structfmt.Println(knd)// iterate through the fields of the struct:for i := 0; i < value.NumField(); i++ {fmt.Printf("Field %d: %v\n", i, value.Field(i))// error: panic: reflect.Value.SetString using value obtained using unexported field//value.Field(i).SetString("C#")}// call the first method, which is String():results := value.Method(0).Call(nil)fmt.Println(results) // [Ada - Go - Oberon]}
