我有一个 struct
,它有一个或多个 struct
成员。每个成员都应实现一个 Validator
接口(interface)。
我想使用反射遍历所有 struct
成员并调用接口(interface)的 Validate()
方法。例如:
package main
import "fmt"
import "reflect"
type Validator interface {
Validate()
}
type T1 struct {
S string
}
func (p *T1) Validate() {
fmt.Println("HERE 1")
}
type T2 struct {
S string
}
func (p *T2) Validate() {
fmt.Println("HERE 2")
}
type Top struct {
S1 T1
S2 T2
}
func main() {
var t Top
r := reflect.ValueOf(t)
for i := 0; i < r.NumField(); i++ {
f := r.Field(i)
if f.Kind() == reflect.Struct {
validator := f.Interface().(Validator)
validator.Validate()
}
}
}
运行时输出:
panic: interface conversion: main.T1 is not main.Validator: missing method Validate
如果我更改 Validate()
方法以接受值(而不是指针)接收器,那么它就可以工作。但是,我想使用指针接收器,因为结构
可能会变得很大。
如何更改反射代码以在定义的方法采用指针接收器的情况下工作?
我也试过使用这条线:
validator := f.Addr().Interface().(Validator)
获取一个指针,然后输出:
panic: reflect.Value.Addr of unaddressable value
最佳答案
您的值都不可寻址,因此您不能使用指针接收器调用它们的任何方法。
如果 S1
和 S2
字段不能是指针,如果您有指向 Top
结构的指针,您仍然可以寻址它们:
r := reflect.ValueOf(&t).Elem()
for i := 0; i < r.NumField(); i++ {
f := r.Field(i)
if f.Kind() == reflect.Struct {
validator := f.Addr().Interface().(Validator)
validator.Validate()
}
}
关于go - 使用反射迭代结构的结构成员并在其上调用方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49162418/