在 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中文网其他相关文章!