go - 使用反射迭代结构的结构成员并在其上调用方法

标签 go methods struct reflection interface

我有一个 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

最佳答案

您的值都不可寻址,因此您不能使用指针接收器调用它们的任何方法。

如果 S1S2 字段不能是指针,如果您有指向 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/

相关文章:

c# - C# 中的结构与类 - 请解释行为

c++ - 对静态常量结构的 undefined reference

go - 在遍历 slice 并通过 "slice bounds out of range"修改它时出现 "append()"错误

在带有指针的函数循环中调用的 Goroutine 会覆盖值吗?

java |如何使用反射和 RTTI 计算所有方法?

java获取静态方法的类名

swift - 来自枚举的类参数

go - 接口(interface)转换: interface {} is float64 not []interface {} PubNub

google-maps - Golang Google Maps API 到达方式

c++ - 类有虚方法但非虚析构函数C++