面试题答案
一键面试反射实现动态类型操作原理
在Go语言中,反射基于三个核心类型实现动态类型操作:reflect.Type
、reflect.Value
和 reflect.Kind
。
- 获取反射对象:通过
reflect.TypeOf
和reflect.ValueOf
函数,分别获取值的类型信息(reflect.Type
)和值本身的可操作表示(reflect.Value
)。 - 动态操作依据:
reflect.Value
提供了一系列方法来动态读取、修改值,reflect.Type
用于获取类型相关信息,如字段、方法等。reflect.Kind
则表示值的底层类型,用于判断值的种类。
实际场景应用举例
- 动态调用函数:
package main
import (
"fmt"
"reflect"
)
func add(a, b int) int {
return a + b
}
func main() {
f := reflect.ValueOf(add)
args := []reflect.Value{reflect.ValueOf(3), reflect.ValueOf(5)}
result := f.Call(args)
fmt.Println(result[0].Int())
}
在上述代码中,先通过 reflect.ValueOf
获取函数 add
的 reflect.Value
,然后构建参数列表 args
,调用 Call
方法实现动态调用函数,最后从返回值列表中获取结果。
2. 动态访问结构体字段:
package main
import (
"fmt"
"reflect"
)
type Person struct {
Name string
Age int
}
func main() {
p := Person{"John", 30}
valueOf := reflect.ValueOf(&p).Elem()
field := valueOf.FieldByName("Name")
if field.IsValid() {
fmt.Println(field.String())
}
ageField := valueOf.FieldByName("Age")
if ageField.IsValid() {
ageField.SetInt(31)
fmt.Println(p.Age)
}
}
这里通过 reflect.ValueOf
获取结构体指针的 reflect.Value
,再使用 Elem
方法获取结构体实例的 reflect.Value
。然后通过 FieldByName
方法根据字段名获取字段,进行读取和修改操作。