我有这个类型的实现:
type A struct{
name string
}
func (a A) getName() string {
return "My name is " + a.name
}
我如何使用反射更改此类型的方法getName()的实现?例如,我想要使用下面的实现而不是当前的实现:
func newGetName() string {
return "test reflection"
}
我有这个类型的实现:
type A struct{
name string
}
func (a A) getName() string {
return "My name is " + a.name
}
我如何使用反射更改此类型的方法getName()的实现?例如,我想要使用下面的实现而不是当前的实现:
func newGetName() string {
return "test reflection"
}
Go是一种编译语言,因此不可能在运行时修改事物的实现。您可以更改函数指针指向的位置:
var getName func(string) = func(name string) {
return "my name is " + name
}
getName
添加为A
的成员:type A struct {
name string
getName func() string
}
然后我们将指向该结构体的指针作为隐式参数(即闭包)封装:
foo := &A{name: "Hans"}
foo.getName = func() string {
return "my name is " + name
}
A.getName()
函数,结果为 "我的名字是汉斯"
。你可以正常使用方法表达式和其他许多特性,但是 getName
是一个 结构体成员 而不是 A
的 方法,所以请记住这一点。如果你想给 getName
赋予新的含义,请将其分配为不同的值:foo.getName = func() string {
return "test reflection"
}
如果您预先知道getName
可能会有哪些实现,另一个特别适用的想法是向A
添加一个新成员,指出getName
目前拥有哪种实现,然后切换到该变量。
请查看这个例子:
包 main
import "fmt"
type Aer interface {
getName() string
}
type A struct {
name string
}
func (a A) getName() string {
return "My name is " + a.name
}
type testA struct {
a A
}
func (ta testA) getName() string {
return "NEW: My name is " + ta.a.name
}
func main() {
a := A{name: "nameA"}
fmt.Println(a.getName())
ta := testA{a: a}
fmt.Println(ta.getName())
}
输出:
My name is nameA
NEW: My name is nameA
unsafe
和 reflct.MakeFunc()
存在一些技巧可能会奏效,但除了挑战之外,这真的不是任何人在现实生活中都应该做的事情。 - Not_a_Golfer