【问题标题】:Using reflect, how to create struct "type" dynamically?使用反射,如何动态创建结构“类型”?
【发布时间】:2018-12-27 21:25:12
【问题描述】:

考虑以下结构:

type Foo struct{}

func (f *Foo) foo() {
    fmt.Println("Hello")
}

使用反射我想生成一个覆盖一组方法的自定义结构类型。 手动完成工作时,我想做的是:

type Edit struct{
    Foo
}

func (e *Edit) foo() {
    e.Foo.foo()
    fmt.Println("World")
}

但我不想手动编写这个,而是想创建一个函数,自动为任何给定的结构执行这种覆盖。


我知道我可以使用 :

实例化一个结构体
res := reflect.New(reflect.TypeOf(origin))

但在这种情况下,我们无法编辑方法。

那么如何使用反射创建一个结构类型来包装现有类型,就像上面解释的那样?

【问题讨论】:

  • 在运行时做这样的事情与 Go 不是特别兼容。不过,这对于生成器来说可能是一个很好的用例,请参阅 go generate。
  • @Adrian:谢谢,但如果不是这样,我不确定还有什么其他答案。
  • 确实这些问题与我想要的无关。理想情况下,我想避免代码生成
  • 为什么要避免代码生成? Go 不支持在运行时创建方法。您的选择有限。
  • 因为这是一个图书馆。所以我想避免强迫图书馆用户使用代码生成。虽然这可能是不可能的

标签: go reflection


【解决方案1】:

您可以使用Method Values 实现与您要求的非常相似的东西。您可以执行以下操作:

package main

import (
    "fmt"
)

type Foo struct {
    sayHelloAgain func()
}

func (f *Foo) SayHello() { 
    fmt.Print("Hello,")
    f.sayHelloAgain() 
}

func main() {
    edit := struct{Foo}{}
    edit.sayHelloAgain = func(){ fmt.Println(" World!") }
    edit.SayHello()

}

Go Playground

如您所见,您可以创建一个匿名结构,该结构将能够调用SayHello 函数,然后该函数调用接收者的动态设置sayHelloAgain 方法。

我认为这将是您最接近目标的方式,并且按照您的要求工作(没有relection)

【讨论】:

  • 感谢您的想法,但这并不符合我想要实现的目标
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2020-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-02-25
  • 1970-01-01
相关资源
最近更新 更多