ホームページ >バックエンド開発 >Golang >Go でインターフェイス ポインターのメソッドを正しく呼び出すにはどうすればよいですか?

Go でインターフェイス ポインターのメソッドを正しく呼び出すにはどうすればよいですか?

DDD
DDDオリジナル
2024-12-14 19:31:11205ブラウズ

How to Correctly Call Methods on Interface Pointers in Go?

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。