在Go 中呼叫介面指標上的方法
在Go 中,針對介面進行程式設計時,您可能會遇到需要能夠呼叫指向介面值的指標上的方法。當您想要存取介面本身未直接公開的底層方法時,可能會發生這種情況。
考慮以下場景:
package main import "fmt" // SqlExecutor interface type SqlExecutor interface { Get(i interface{}, key interface{}) (interface{}, error) } // GorpDbMap and GorpTransaction implement SqlExecutor type GorpDbMap struct{} type GorpTransaction struct{} func (db GorpDbMap) Get(i interface{}, key interface{}) (interface{}, error) { return nil, nil } func (tx GorpTransaction) Get(i interface{}, key interface{}) (interface{}, error) { return nil, nil } func main() { // Initialize a GorpDbMap or GorpTransaction dbMap := GorpDbMap{} transaction := GorpTransaction{} // Create a repository that uses the SqlExecutor interface repo := Repository{ // This will result in an error Gorp: &dbMap, } // Try to call Get method on the pointer to the SqlExecutor interface obj, err := repo.GetById(1, 2) if err != nil { fmt.Println(err) } fmt.Println(obj) } // Repository demonstrates calling methods on interface pointers type Repository struct { Gorp SqlExecutor } func (r Repository) GetById(i interface{}, key interface{}) interface{} { obj, err := r.Gorp.Get(i, key) if err != nil { panic(err) } return obj }
執行上述程式碼時,您將遇到以下錯誤:
r.Gorp.Get undefined (type *gorp.SqlExecutor has no field or method Get)
出現此錯誤是因為在呼叫SqlExecutor 介面值的指標之前沒有正確取消引用Get 方法。
要解決此問題,您需要使用星號運算子 (*) 取消對介面值的指標的參考。這可以透過以下修改程式碼來完成:
func main() { // Initialize a GorpDbMap or GorpTransaction dbMap := GorpDbMap{} transaction := GorpTransaction{} // Create a repository that uses the SqlExecutor interface repo := Repository{ Gorp: &dbMap, } // Try to call Get method on the pointer to the SqlExecutor interface obj, err := (*repo.Gorp).Get(1, 2) if err != nil { fmt.Println(err) } fmt.Println(obj) }
透過取消引用介面值的指針,您現在可以存取實作該介面的結構體的底層方法。在這種情況下,GorpDbMap 結構體的 Get 方法會成功呼叫。
需要注意的是,在 Go 中,通常建議優先按值傳遞值,而不是傳遞指向值的指標。這有助於防止對原始值的無意修改。對於接口,您通常應該傳遞接口值本身,而不是指向接口值的指標。
以上是Go中如何正確呼叫介面指標方法?的詳細內容。更多資訊請關注PHP中文網其他相關文章!