ホームページ バックエンド開発 Golang 値レシーバーを使用して構造体を使用して、ポインター レシーバーを使用してインターフェイスを実行できないのはなぜですか?

値レシーバーを使用して構造体を使用して、ポインター レシーバーを使用してインターフェイスを実行できないのはなぜですか?

Dec 04, 2024 am 01:40 AM

Why Can't Go Structs with Value Receivers Fulfill Interfaces with Pointer Receivers?

なぜ Go 構造体変数はポインタ レシーバを備えたインターフェイスを実装できないのですか?

Go では、構造体メソッドはどちらかの値レシーバ (動作する) を持つことができます。構造体の値を直接操作する)、またはポインター レシーバー (構造体へのポインターを操作する)。インターフェイスを実装する場合、インターフェイス メソッドの受信側の型に応じて、どの型がインターフェイスを満たすことができるかについて微妙な制限があります。

次のコードを考慮してください。

type greeter interface {
    hello()
    goodbye()
}

type tourGuide struct {
    name string
}
ログイン後にコピー

次のコードを使用してメソッドを定義できます。 TourGuide の値とポインターの両方のレシーバー:

func (t tourGuide) hello() {
    fmt.Println("Hello", t.name)
}

func (t *tourGuide) goodbye() {
    fmt.Println("Goodbye", t.name)
}
ログイン後にコピー

さて、ここにキーがあります違い:

  • tourGuide の変数またはコピーは、値とポインターの両方のレシーバー メソッドを呼び出すことができます:

    var t1 tourGuide = tourGuide{"James"}
    t1.hello()   // works
    t1.goodbye() // works
    ログイン後にコピー
  • ただし、インターフェイス変数は、インターフェイスと同じレシーバー型を持つすべてのインターフェイス メソッドを実装できる型から割り当てられます。それ自体:

    var g2 greeter = &t2 // works because *tourGuide implements greeter's pointer receiver methods
    
    // illegal: t1 is not assignable to g1
    // var g1 greeter = t1 // error: cannot use tourGuide as type greeter in assignment because tourGuide does not implement greeter (hello method has value receiver)
    ログイン後にコピー

では、なぜ t1 はグリーター インターフェイスを実装できないのでしょうか?

その理由は、グリーター インターフェイスの hello() メソッドにポインター レシーバー。レシーバーとして TourGuide 値へのポインターを期待することを意味します。ただし、t1 は変数です (ポインタではありません)。値変数はアドレス指定可能ですが、インターフェイス値は参照ではなく、保存された値のコピーを保持します。したがって、値変数をインターフェイス変数に割り当てると、逆参照できない新しいコピーが作成され、ポインター レシーバー メソッドのレシーバーとして渡されます。

要約すると、ポインター レシーバー メソッドを使用してインターフェイスを実装する場合、ポインターのみが作成されます。実装型へのインターフェイスを満たすことができます。値の変数またはコピーは、必要なポインター レシーバーの型を提供できないため、このようなインターフェイスに割り当てることはできません。

以上が値レシーバーを使用して構造体を使用して、ポインター レシーバーを使用してインターフェイスを実行できないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットな記事タグ

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか? Mar 03, 2025 pm 05:17 PM

Go Language Packのインポート:アンダースコアとアンダースコアなしの違いは何ですか?

Beegoフレームワークのページ間で短期情報転送を実装する方法は? Beegoフレームワークのページ間で短期情報転送を実装する方法は? Mar 03, 2025 pm 05:22 PM

Beegoフレームワークのページ間で短期情報転送を実装する方法は?

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

GOでテスト用のモックオブジェクトとスタブを書くにはどうすればよいですか?

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか? Mar 10, 2025 pm 05:36 PM

トレースツールを使用して、GOアプリケーションの実行フローを理解するにはどうすればよいですか?

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は? Mar 03, 2025 pm 05:18 PM

MySQLクエリ結果リストをGO言語のカスタム構造スライスに変換する方法は?

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか? Mar 10, 2025 pm 03:20 PM

GOのジェネリックのカスタムタイプ制約を定義するにはどうすればよいですか?

Go言語でファイルを便利に書く方法は? Go言語でファイルを便利に書く方法は? Mar 03, 2025 pm 05:15 PM

Go言語でファイルを便利に書く方法は?

Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか? Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか? Mar 10, 2025 pm 05:38 PM

Linterと静的分析ツールを使用して、GOコードの品質と保守性を向上させるにはどうすればよいですか?

See all articles