業務でGO言語を扱うことになり、必死に勉強していたのですが、
ポインタが最初はなかなか理解できずに苦労しました。
今回はそんなポインタとはなんぞやという方に向けて解説していきたいと思います。
※自分もまだまだ未熟なため、一部不適切な部分があるかもしれませんが、ご了承ください。
ポインタを理解するために抑えておくべき用語
・メモリ ・アドレス ・値渡し一応、さらっと用語について解説します。
#メモリとアドレス
メモリはデータを一時的に保存する場所ですね。
メモリに変数が格納され、変数に値が格納されています。
つまり、 メモリ<変数<値(文字列とか数値)という構造になります。
メモリは広大な野原だと思ってください。
その野原に変数という名の箱がたくさん置かれています。
多すぎて、どれが何の箱なのかわかりません。
なので、箱ごとに住所をつけて管理をします。
その住所がアドレスです。
a := "asfd"
fmt.Println(&a) // 0xc00008e1e0
実際のアドレスはこのように文字と数字の羅列(16進数)で表されています。
#値渡し
値渡しは関数の呼び出し方の方法の一つです。
重要なのは、引数に指定した値のコピーが関数内部で使用されるということです。
func printValue(a string) {
a := "fuga"
fmt.Println(a)
}
value := "hoge"
printValue(value)
// 出力結果 "fuga"
fmt.Println(value)
// 出力結果 "hoge"
値渡しは値をコピーして渡しているだけなので、
関数内で引数の値を書き換えても、呼び出し元で指定した引数(value)の値は変わりません。
いよいよポインタの説明に入ります。
#ポインタとは何か
ポインタとは実際のアドレスを指定したデータ型。及び、変数のことです
ポインタ型は「*変数名」とすることで生成することができます
実際にコードを見ながら解説していきます。
func printValue(a *string) {
//valueの値を直接書き換えている
*a = "fuga"
fmt.Println(*a)
}
func main() {
value := "hoge"
fmt.Println(value)
//出力結果 hoge
printValue(&value)
//出力結果 fuga
fmt.Println(value)
//出力結果 fuga
}
「&変数名」でアドレスを参照することができて、「*変数名」は値を参照することができます。
値渡しは値のコピーで元の変数の中身を書き換えることはできない。
ポインタ渡しは実際の値を書き換える。
これが値渡しとポインタ渡しの違いになります。