検索
ホームページバックエンド開発Golangポインタとメソッドの値の違い

The difference between pointers and values on methods

Go でメソッドを記述する場合、重要な決定の 1 つは、構造体を値で渡すかポインターで渡すかです。この選択は、パフォーマンス、コードの動作、メモリ割り当てに影響を与える可能性があります。この投稿では、実際の例を使用してこの違いを検討し、それぞれのアプローチがどのような場合に適切であるかを理解します。

小さな構造体と 2 つのメソッドから始めましょう。1 つは構造体が値によって渡され、もう 1 つはポインタによって渡されます。

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}

値とポインタの違い

構造体をメソッドに値で渡すと、Go は構造体のコピーを作成します。独立したコピーを使用しているため、メソッド内の構造体に加えられた変更は元の構造体には影響しません。

一方、構造体をポインタで渡す場合は、元の構造体のメモリ アドレスを渡します。これは、同じインスタンスを操作しているため、メソッド内の構造体に加えられた変更は、元の構造体を直接変更することを意味します。

要約:

  • 値による: メソッドは構造体のコピーを受け取り、新しいメモリ空間を作成します。

  • ポインタによる: メソッドは、同じメモリ空間を指す、元の構造体のメモリ アドレスを受け取ります。

ヒープ

構造体が値によって渡されると、コピーがスタックに割り当てられます。これは一般に高速で効率的です。ただし、構造体が大きい場合、コピーによって大量のスタック メモリが消費される可能性があります。

構造体がポインターによって渡される場合、ポインター自体はスタック上に割り当てられますが、特に new、make を使用して作成された場合、または匿名関数によってキャプチャされた場合には、元の構造体がヒープ上に割り当てられる可能性があります。

ヒープ割り当ては、割り当て時間とガベージ コレクションの点でより高価ですが、構造体全体をコピーせずに大量のデータを効率的に操作できます。

各アプローチをいつ使用するか

値による

構造体を値で渡すことは、次の場合に役立ちます。

  • 元の構造体が変更されていないことを確認したいと考えています。
  • 構造体は小さいため、コピーしてもパフォーマンスに大きな影響はありません。
  • このメソッドは、内部状態を変更する必要なく、単にデータを読み取るだけです。

例:

func (p Person) GetName() string {
    return p.Name
}

ここで、GetName は Name フィールドのみを読み取り、構造体の状態を変更せずに文字列を返します。

ポインタによる

ポインターによる構造体受け渡しは、次の場合に有益です。

  • 元の構造体を変更する必要があります。
  • 構造体は大きいため、そのデータをコピーするとメモリとパフォーマンスの面でコストがかかります。
  • コードの効率を向上させるために、不必要なコピーを避けたいと考えています。

例:

package main

import (
    "fmt"
)

type Person struct {
    Name string
    Age  int
}

// Method with struct passed by value
func (p Person) CelebrateBirthdayValue() {
    p.Age++
}

// Method with struct passed by pointer
func (p *Person) CelebrateBirthdayPointer() {
    p.Age++
}

func main() {
    person := Person{Name: "Alice", Age: 30}

    // Passing by value
    person.CelebrateBirthdayValue()
    fmt.Println("After CelebrateBirthdayValue:", person.Age) // Output: 30

    // Passing by pointer
    person.CelebrateBirthdayPointer()
    fmt.Println("After CelebrateBirthdayPointer:", person.Age) // Output: 31
}

この場合、UpdateName は元の構造体の Name フィールドを直接変更します。これは、コピーを作成するよりも効率的です。

結論

Go でメソッドを作成するときに、構造体を値で渡すかポインターで渡すかを決定することは、パフォーマンス、コードの動作、メモリ割り当てに影響を与える可能性がある重要な選択です。

値による受け渡しは、メソッド内で構造体の不変性を確保するのに役立ちますが、ポインターによる受け渡しは、元の構造体を変更して、より大きな構造体を操作する場合のパフォーマンスを最適化するために不可欠です。

以上がポインタとメソッドの値の違いの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

OpenSSLは、安全な通信で広く使用されているオープンソースライブラリとして、暗号化アルゴリズム、キー、証明書管理機能を提供します。ただし、その歴史的バージョンにはいくつかの既知のセキュリティの脆弱性があり、その一部は非常に有害です。この記事では、Debian SystemsのOpenSSLの共通の脆弱性と対応測定に焦点を当てます。 Debianopensslの既知の脆弱性:OpenSSLは、次のようないくつかの深刻な脆弱性を経験しています。攻撃者は、この脆弱性を、暗号化キーなどを含む、サーバー上の不正な読み取りの敏感な情報に使用できます。

PPROFツールを使用してGOパフォーマンスを分析しますか?PPROFツールを使用してGOパフォーマンスを分析しますか?Mar 21, 2025 pm 06:37 PM

この記事では、プロファイリングの有効化、データの収集、CPUやメモリの問題などの一般的なボトルネックの識別など、GOパフォーマンスを分析するためにPPROFツールを使用する方法について説明します。

Goでユニットテストをどのように書きますか?Goでユニットテストをどのように書きますか?Mar 21, 2025 pm 06:34 PM

この記事では、GOでユニットテストを書くことで、ベストプラクティス、モッキングテクニック、効率的なテスト管理のためのツールについて説明します。

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

この記事では、ユニットテストのためにGOのモックとスタブを作成することを示しています。 インターフェイスの使用を強調し、模擬実装の例を提供し、模擬フォーカスを維持し、アサーションライブラリを使用するなどのベストプラクティスについて説明します。 articl

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

この記事では、GENICSのGOのカスタムタイプの制約について説明します。 インターフェイスがジェネリック関数の最小タイプ要件をどのように定義するかを詳しく説明し、タイプの安全性とコードの再利用性を改善します。 この記事では、制限とベストプラクティスについても説明しています

Goの反射パッケージの目的を説明してください。いつリフレクションを使用しますか?パフォーマンスへの影響は何ですか?Goの反射パッケージの目的を説明してください。いつリフレクションを使用しますか?パフォーマンスへの影響は何ですか?Mar 25, 2025 am 11:17 AM

この記事では、コードのランタイム操作に使用されるGoの反射パッケージについて説明します。シリアル化、一般的なプログラミングなどに有益です。実行やメモリの使用量の増加、賢明な使用と最高のアドバイスなどのパフォーマンスコストについて警告します

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

この記事では、トレースツールを使用してGOアプリケーションの実行フローを分析します。 手動および自動計装技術について説明し、Jaeger、Zipkin、Opentelemetryなどのツールを比較し、効果的なデータの視覚化を強調しています

GOでテーブル駆動型テストをどのように使用しますか?GOでテーブル駆動型テストをどのように使用しますか?Mar 21, 2025 pm 06:35 PM

この記事では、GOでテーブル駆動型のテストを使用して説明します。これは、テストのテーブルを使用して複数の入力と結果を持つ関数をテストする方法です。読みやすさの向上、重複の減少、スケーラビリティ、一貫性、および

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強力な PHP 統合開発環境

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser は、オンライン試験を安全に受験するための安全なブラウザ環境です。このソフトウェアは、あらゆるコンピュータを安全なワークステーションに変えます。あらゆるユーティリティへのアクセスを制御し、学生が無許可のリソースを使用するのを防ぎます。

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

WebStorm Mac版

WebStorm Mac版

便利なJavaScript開発ツール

AtomエディタMac版ダウンロード

AtomエディタMac版ダウンロード

最も人気のあるオープンソースエディター