Golang Reflect Methods for Any type [已关闭]

Golang Reflect Methods for Any type [closed]

提问人:Krum110487 提问时间:11/10/2023 最后编辑:Krum110487 更新时间:11/15/2023 访问量:71

问:


想改进这个问题吗?通过编辑这篇文章添加详细信息并澄清问题。

14天前关闭。

截至 13 天前,社区正在审查是否重新讨论这个问题。

几天来,我一直在为此而烦恼。

我的目标是拥有这样的功能:

func ListFuncs(x any) []string {
    inst := reflect.New(reflect.TypeOf(x))
    y := inst.Elem().Interface()

    t := reflect.TypeOf(y)
    var s []string
    for i := 0; i < t.NumMethod(); i++ {
        s = append(s, t.Method(i).Name)
    }

    return s
}

我知道上面的代码并不完全有意义,但我一直在不停地更改它,它应该给出我想做什么的基本想法,但我不能在我的一生中列出“任何”的函数。当我把它写到我知道的班级时,我什至无法让它工作。

我只能在这样做时让它工作,这是否可能在没有明确知道所使用的结构或为所有可能的结构提供 switch 语句的情况下做到这一点?reflect.TypeOf(StructName{})

编辑:

我试图反思的班级的例子是:

type Core struct {
}

func (c *Core) DirAcceptPathInfo(dir parser.DirectiveEntry, req *http.Request, runCtx *htaccess.Context) error {
    //TODO: AcceptPathInfo directive
    return errors.New("AcceptPathInfo is not yet implemented")
}

如果我做func(c Core)DireAcceptPathInfo,这似乎有效... 嘎!我能解释为什么它适用于一个而不适用于另一个吗?

即使将 y 取消引用为 &y,我也无法让它在 (c *Core) 时工作,我认为这是问题所在。我可以轻松地将它们全部转换为不使用指针,这对我来说不是问题,我只是好奇为什么它不起作用。当我这样做时,它确实有效:

func ListFuncs(x any) []string {
        t := reflect.TypeOf(&Core{})
        var s []string
        for i := 0; i < t.NumMethod(); i++ {
            s = append(s, t.Method(i).Name)
        }
    
        return s
    }

编辑 2:我无法将其设置为已解决,但对于将来寻找此代码的任何人,我最终得到了这段代码,这要归功于 Marrow 和下面评论中所有乐于助人的人!

这段代码允许我获取函数名称和函数本身来调用它。https://go.dev/play/p/RyNEF_Frh9g

func ListFuncs2(x any) []string {
    v := reflect.ValueOf(x)
    t := v.Type()
    if t.Kind() != reflect.Ptr {
        v = reflect.New(t)
        t = v.Type()
    }

    s := make([]string, 0, t.NumMethod())
    for i := 0; i < t.NumMethod(); i++ {
        s = append(s, t.Method(i).Name)
        f := v.MethodByName(t.Method(i).Name).Interface().(func(string) error)
        f("Test")
    }
    return s
}
Go 方法 反射

评论

0赞 Volker 11/10/2023
怎么了?您可能应该提供您实际遇到问题的测试用例。阅读博客文章“反射定律”。t := reflect.TypeOf(x); var s []string; for i := 0; i < t.NumMethod(); i++ { s = append(s, t.Method(i).Name) }
2赞 icza 11/10/2023
请指出您的问题是什么。您的代码虽然不是最佳的,但可以正常工作。
2赞 mkopriva 11/10/2023
也许您的方法未导出(以小写字母或下划线开头)?go.dev/play/p/_XVRm1Jry3V
0赞 Krum110487 11/10/2023
所以,它们被出口了,但似乎我所有的都是像你一样出口的,而不是像你一样。我想这就是区别。func (sn *structName) Func1() {}
1赞 Marrow父 11/11/2023
这将取决于你是否这样做或 - 如果你只是这样做,你不会看到,因为它的接收器是(即你只传递了struct,但方法接收器在struct ptr上)。您可以调整您的处理方式 - 尝试 go.dev/play/p/YemlegTcZn5ListFuncs(Core{})ListFuncs(&Core{})ListFuncs(Core{})DirAcceptPathInfo(c *Core)ListFuncs

答: 暂无答案