我有一個包含許多字段的結(jié)構(gòu)類型,這些字段都實現(xiàn)了 Renderer 接口。字段類型實現(xiàn)了與指針接收器的接口。我想要一個接受字段名稱并調(diào)用該字段上的 Render 方法的函數(shù)。我能夠找到該字段并獲得大量有關(guān)它的信息,但是由于指針接收器的原因,進行類型斷言似乎讓我很頭疼。這是一些顯示我的問題的代碼:package mainimport (? ? "fmt"? ? "reflect")type Renderer interface {? ? Render()}type First struct {? ? ExampleField Field}type Field []intfunc (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 并且當我調(diào)用 Interface() 時它似乎是底層類型。如果我切換到非指針接收器,那么第一個函數(shù)就可以工作。我發(fā)現(xiàn)反射值接口和指針接收器這似乎幾乎正是我要問的,問題得到了回答,但如果我實際上調(diào)用了操場鏈接中顯示的 isZeroer 方法,它總是錯誤的,所以它實際上似乎沒有回答這個問題。似乎Addr是關(guān)鍵,因為它特別提到了指針接收器,但我正在努力將其強制返回到接口中。
1 回答

喵喵時光機
TA貢獻1846條經(jīng)驗 獲得超7個贊
使用此代碼:
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()
}
}
關(guān)鍵是要改:
structVal := reflect.ValueOf(*f)
到:
structVal := reflect.ValueOf(f).Elem()
問題中使用的語句創(chuàng)建了一個不可尋址的結(jié)構(gòu)值。不可尋址結(jié)構(gòu)中的字段也不可尋址,因此無法訪問字段上的指針接收器。
此答案中使用的語句創(chuàng)建了一個可尋址的結(jié)構(gòu)值。
- 1 回答
- 0 關(guān)注
- 122 瀏覽
添加回答
舉報
0/150
提交
取消