![](/img/trans.png)
[英]Why does putting a pointer in an interface{} in Go cause reflect to lose the name of the type?
[英]Go Reflect field name to specific interface
我有一个带有许多字段的struct类型,这些字段都实现了Renderer接口。 字段类型实现与指针接收器的接口。 我想要一个具有字段名称并在该字段上调用Render方法的函数。 我能够找到该字段并获得很多有关它的信息,但是由于指针接收器的原因,执行类型断言似乎让我很吃力。 这是一些显示我的问题的代码:
package main
import (
"fmt"
"reflect"
)
type Renderer interface {
Render()
}
type First struct {
ExampleField Field
}
type Field []int
func (f *Field) Render() {
fmt.Println("Hello from first")
}
func main() {
f := First{
Field{1, 2, 3},
}
f.ExampleField.Render()
renderField("ExampleField", &f)
renderField2("ExampleField", &f)
}
func renderField(field string, f *First) {
structVal := reflect.ValueOf(*f)
renderType := reflect.TypeOf((*Renderer)(nil)).Elem()
fieldToRender := structVal.FieldByName(field)
fieldPtr := reflect.PtrTo(fieldToRender.Type())
fmt.Printf("Implements? %v\n", fieldPtr.Implements(renderType))
fmt.Printf("Addressable? %v\n", fieldToRender.CanAddr())
fieldInter := fieldToRender.Interface()
if renderer, ok := fieldInter.(Renderer); ok {
// Pointer receiver so this never gets called
fmt.Print("Able to cast")
renderer.Render()
}
}
func renderField2(field string, f *First) {
structVal := reflect.ValueOf(*f)
fieldToRender := structVal.FieldByName(field)
vp := reflect.New(reflect.TypeOf(fieldToRender))
vp.Elem().Set(reflect.ValueOf(fieldToRender))
vpAddr := vp.Elem().Addr()
typeVal := vpAddr.Interface()
fmt.Println(typeVal) // <main.Field Value>⏎
renderer := typeVal.(Renderer)
renderer.Render()
// interface conversion: *reflect.Value is not main.Renderer: missing method Render
}
renderField2似乎使我接近,但是Addr()给我一个* Reflect.Value,当我调用Interface()时,它似乎是基础类型。 如果我切换到非指针接收器,则第一个功能有效。 我发现反射值接口和指针接收器似乎与我要问的几乎完全相同,并且回答了该问题,但是如果我实际上调用了游乐场链接中提供的isZeroer方法,则它始终为false,因此实际上似乎没有答案问题。
似乎Addr是关键,因为它专门提到了指针接收器,但是我正在努力将其强制返回接口。
使用此代码:
func renderField(name string, f *First) {
structVal := reflect.ValueOf(f).Elem()
field := structVal.FieldByName(name).Addr().Interface()
if renderer, ok := field.(Renderer); ok {
renderer.Render()
}
}
关键是要更改:
structVal := reflect.ValueOf(*f)
至:
structVal := reflect.ValueOf(f).Elem()
问题中使用的语句创建了一个不可寻址的结构值。 不可寻址结构中的字段也是不可寻址的,因此无法访问这些字段上的指针接收器。
此答案中使用的语句创建一个可寻址的结构值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.