ホームページ > バックエンド開発 > Golang > golang でのポインタの受け渡しと値の受け渡しの違いは何ですか?

golang でのポインタの受け渡しと値の受け渡しの違いは何ですか?

青灯夜游
リリース: 2019-12-30 11:56:21
オリジナル
3474 人が閲覧しました

Go では、パラメーターをポインター (参照とも呼ばれます) と値によって渡すことができます。この記事では、選択に影響を与える可能性のあるさまざまな状況に特に注意を払いながら、2 つのアプローチを比較します。

golang でのポインタの受け渡しと値の受け渡しの違いは何ですか?

ポインタの受け渡しと値の受け渡し

厳密に言えば、go のメソッドまたは関数の受け渡しメソッドは 1 つだけです。それは値渡しだけです。変数が引数として渡されるたびに、変数の新しいコピーが作成され、呼び出される関数またはメソッドに渡されます。コピーは異なるメモリ アドレスに割り当てられます。

変数をポインタで渡す場合、同じメモリ アドレスを指す新しいコピーが作成されます。違いを感じるために、それがどのように機能するかを見てみましょう。

値の受け渡し

package main

import "fmt"

type Person struct {  
    firstName string
    lastName  string
}

func changeName(p Person) {  
    p.firstName = "Bob"
}

func main() {  
    person := Person {
        firstName: "Alice",
        lastName: "Dow",
    }

    changeName(person)

    fmt.Println(person)
}
ログイン後にコピー

コードを実行すると次の出力が得られます:

{Alice Dow}
ログイン後にコピー

関数changeNameによってfirstNameが「Bob」に変更されることに注意してください。 ", この変更は、main 関数の変数 person には影響しません。これは、関数changeNameがperson自体ではなく、変数personのコピーを変更するために発生します。

ポインターの受け渡し

package main
import "fmt"
type Person struct {  
    firstName string
    lastName  string
}
func changeName(p *Person) {  
    p.firstName = "Bob"
}
func main() {  
    person := Person {
        firstName: "Alice",
        lastName: "Dow",
    }
    changeName(&person)
    fmt.Println(person)
}
ログイン後にコピー

コードを実行すると次の出力が得られます:

{Bob Dow}
ログイン後にコピー

この場合、関数 main の変数 person は関数changeNameが変更されました。これは、&person と p が、同じメモリ アドレスに格納されている同じ構造体への 2 つの異なるポインタであるために発生します。

変数は変更できません

値で渡す以外に選択肢はありません。したがって、この変数はダウンストリームで変更できません。逆に、変数が変更されることが予想される場合は、ポインターを介して変数を渡す必要があります。

変数が大きな構造体である

変数が大きな構造体であり、パフォーマンスが問題となる場合は、ポインターを介して変数を渡すことが最善です。これにより、メモリ内の構造全体をコピーすることが回避されます。

変数はマップまたはスライスです

Go のマップとスライスは参照型であり、値によって渡される必要があります。

値渡しは通常、より低コストです。

Go は C に少し似ていますが、コンパイラの動作は異なります。 C の例えは Go では常に機能するとは限りません。値による受け渡しは、Go でのポインターによる受け渡しよりもコストが低い場合があります。これは、Go がエスケープ解析を使用して変数を関数のスタック フレームに安全に割り当てることができるかどうかを判断するために発生します。これは、変数をヒープに割り当てるよりもはるかに低コストである可能性があります。値渡しにより、Go でのエスケープ分析が簡素化され、変数への代入の機会が向上します。

#概要

ポインタ渡しと値渡しの違い

1. ポインタ渡しはアドレスであり、アドレス内のデータではありません。転送するデータが少なく、値の転送よりも効率的です。一般に、値の転送の代わりにポインタを使用できます。

2. ポインタが渡されると、呼び出し元関数のポインタが指す空間データの変更は呼び出し元に影響を与えますが、同じ領域を指しているため、ポインタの転送は呼び出し元のデータには影響しません。データ。

関連する推奨事項:

golang チュートリアル

以上がgolang でのポインタの受け渡しと値の受け渡しの違いは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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