在本文中,我們將探討嘗試動態呼叫介面{}上的方法時面臨的問題在圍棋。我們的目標是克服這項挑戰,無論底層資料類型或接收器類型為何,都能實現高效的方法呼叫。
在Go 中處理interface{} 時,我們遇到了以下限制:動態方法呼叫:如果儲存在interface{}中的資料是一個指針,我們在存取它的地址時會遇到困難。因此,無法動態呼叫帶有指標接收器的方法。
為了解決此問題,我們利用了一種包含四種情況的技術:
確定適當的資料類型後,我們對值和指標上的方法是否存在執行附加檢查。透過這樣做,我們可以確保方法調用,無論該方法是否被聲明為值或指標接收器。
以下程式碼示範了我們解決方案的實作:
package main import ( "fmt" "reflect" ) type Test struct { Start string } // value receiver func (t Test) Finish() string { return t.Start + "finish" } // pointer receiver func (t *Test) Another() string { return t.Start + "another" } func CallMethod(i interface{}, methodName string) interface{} { var ptr reflect.Value var value reflect.Value var finalMethod reflect.Value value = reflect.ValueOf(i) // if we start with a pointer, we need to get value pointed to // if we start with a value, we need to get a pointer to that value if value.Type().Kind() == reflect.Ptr { ptr = value value = ptr.Elem() } else { ptr = reflect.New(reflect.TypeOf(i)) temp := ptr.Elem() temp.Set(value) } // check for method on value method := value.MethodByName(methodName) if method.IsValid() { finalMethod = method } // check for method on pointer method = ptr.MethodByName(methodName) if method.IsValid() { finalMethod = method } if (finalMethod.IsValid()) { return finalMethod.Call([]reflect.Value{})[0].Interface() } // return or panic, method not found of either type return "" } func main() { i := Test{Start: "start"} j := Test{Start: "start2"} fmt.Println(CallMethod(i, "Finish")) fmt.Println(CallMethod(&i, "Finish")) fmt.Println(CallMethod(i, "Another")) fmt.Println(CallMethod(&i, "Another")) fmt.Println(CallMethod(j, "Finish")) fmt.Println(CallMethod(&j, "Finish")) fmt.Println(CallMethod(j, "Another")) fmt.Println(CallMethod(&j, "Another")) }
透過採用這種技術,我們可以動態呼叫interface{} 上的方法,而不管接收者類型如何,從而促進Go 中的健壯且適應性強的程式碼。
以上是無論接收器類型為何,如何在 Go 中動態呼叫「interface{}」上的方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!