[英]How do you call a method on a struct with a pointer receiver using reflection?
I am working with reflection in Go and have some issues trying to call a method on a struct that has a pointer receiver.我正在使用 Go 中的反射,并且在尝试在具有指针接收器的结构上调用方法时遇到一些问题。 I have the following go code:
我有以下 go 代码:
package main
import (
"fmt"
"reflect"
)
type Base struct {
Name string
Greeting string
}
func (b *Base) SetGreeting() {
b.Greeting = fmt.Sprintf("Hello %s\n", b.Name)
}
func main() {
var pointer interface{}
// create a new instance of base
mybase := Base{
Name: "reflect",
}
// create a pointer to the base
pointer = &mybase
s := reflect.ValueOf(pointer).Elem()
// get the value of s which should be a pointer
vv := reflect.ValueOf(s)
switch vv.Kind() {
case reflect.Struct:
fmt.Println("struct")
case reflect.Ptr:
fmt.Println("pointer")
}
// output struct property
fmt.Println(s.FieldByName("Name").String())
// call the method using reflect
sayHelloFunc := s.MethodByName("SetGreeting")
if sayHelloFunc.IsValid() {
sayHelloFunc.Call([]reflect.Value{})
} else {
fmt.Println("Unable to find method")
}
fmt.Println(s.FieldByName("Greeting").String())
}
The above is available at https://play.golang.org/p/V04m3LJlRia以上内容可在https://play.golang.org/p/V04m3LJlRia
If I change the method to use a value receiver then the method works, but I am not able to get the Greeting
property.如果我将方法更改为使用值接收器,则该方法有效,但我无法获取
Greeting
属性。 If use the pointer receiver (as in the code) the method cannot be found but I can access the property.如果使用指针接收器(如代码中所示),则找不到该方法,但我可以访问该属性。
How can I do both?我怎样才能做到这两点?
Thanks to @Volker this is now working.感谢@Volker,这现在可以工作了。 The slightly modified code is:
稍作修改的代码是:
package main
import (
"fmt"
"reflect"
)
type Base struct {
Name string
Greeting string
}
func (b *Base) SetGreeting() {
b.Greeting = fmt.Sprintf("Hello %s\n", b.Name)
}
func main() {
var pointer interface{}
// create a new instance of base
mybase := Base{
Name: "reflect",
}
// create a pointer to the base
pointer = &mybase
s := reflect.ValueOf(pointer)
// get the value of s which should be a pointer
vv := reflect.ValueOf(s)
switch vv.Kind() {
case reflect.Struct:
fmt.Println("struct")
case reflect.Ptr:
fmt.Println("pointer")
}
// output struct property
fmt.Println(s.Elem().FieldByName("Name").String())
// call the method using reflect
sayHelloFunc := s.MethodByName("SetGreeting")
if sayHelloFunc.IsValid() {
sayHelloFunc.Call([]reflect.Value{})
} else {
fmt.Println("Unable to find method")
}
fmt.Println(s.Elem().FieldByName("Greeting").String())
}
As can be seen s
is no longer set as a pointer and the method can be called.可以看出
s
不再设置为指针,可以调用方法。
As I wanted to be able to call the properties on s
I then make it a pointer using .Elem()
and then I can use FieldByName
.因为我希望能够调用
s
上的属性,所以我使用.Elem()
将其设为指针,然后我可以使用FieldByName
。
Updated here https://play.golang.org/p/iiUrB961tUa在这里更新https://play.golang.org/p/iiUrB961tUa
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.