Go ポインター: 値とポインター レシーバー - それは重要ですか?

Barbara Streisand
リリース: 2024-11-07 17:51:02
オリジナル
970 人が閲覧しました

Go Pointers: Value vs. Pointer Receivers - Does it Matter?

Go ポインター: 値とポインター レシーバーを詳しく見る

Go では、ポインターはメモリを効果的に管理し、再利用可能なデータを作成する上で重要な役割を果たします。データ構造。初心者は、特に C/C などの言語とは異なるポインターの概念に取り組むことがよくあります。この記事は、Go ポインターのニュアンスを明確にし、よくある誤解に対処することを目的としています。

Go ツアー #52 から借用した以下のコード スニペットを考えてみましょう。

type Vertex struct {
    X, Y float64
}

func (v *Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}

func main() {
    v := &Vertex{3, 4}
    fmt.Println(v.Abs())
}
ログイン後にコピー

ここでは、構造体を定義します。 Vertex、および頂点の絶対値を計算するメソッド Abs です。 Abs のレシーバ v は Vertex へのポインタです。これは、Abs が頂点へのポインタを操作し、元の頂点への変更を可能にすることを意味します。

次に、コードへのわずかな変更を考えてみましょう。

func (v Vertex) Abs() float64 {
    return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
ログイン後にコピー

興味深いことに、この変更により次のことが起こります。同じ結果です。私たちの質問は次のとおりです: *Vertex を使用するか、Abs のレシーバーとして Vertex を使用するかに違いはありますか?

その答えは、Go の 2 つの基本的なルールにあります:

  1. 値とポインター レシーバーの変換: Go では、値レシーバーを持つメソッドからポインター レシーバーを持つメソッドを派生できます。したがって、 func (v Vertex) Abs() float64 は、追加の実装を自動的に生成します。

    func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X+v.Y*v.Y) }
    func (v *Vertex) Abs() float64 { return Vertex.Abs(*v) }  // GENERATED METHOD
    ログイン後にコピー

    コンパイラは、生成されたメソッドをシームレスに検索し、v がポインタでないにもかかわらず v.Abs() が機能する理由を説明します。 .

  2. 自動アドレス取得: Go は変数のアドレスを自動的に取得できます。これは、ポインター レシーバーを使用せずに変更されたコードで v.Abs() を呼び出す場合、次と同等であることを意味します。

    vp := &v
    vp.Abs()
    ログイン後にコピー

    したがって、明示的に & を使用するかどうかに関係なく、関数は依然として頂点へのポインターを受け取ります。 .

以上がGo ポインター: 値とポインター レシーバー - それは重要ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート