【Go】Goのポインタと構造体について理解する
ポインタ系
ポインタとは「メモリのアドレス情報」のこと。
その「メモリのアドレス情報」は、変数の先頭に &
をつけることで取得可能。
var num int = 10
fmt.Println(num) // 10
fmt.Println(&num) // 0x1400009a020
「メモリのアドレス情報」を格納するには、それ用の特別な型を持った変数を用意する必要がある。
その特別な型が「ポインタ型」であり、ポインタ型で宣言された変数を「ポインタ型変数」と呼ぶ。
以下の例では、&num
でメモリのアドレス情報を取得し、ポインタ型変数である pointer
に格納している。*int
がポインタ型を示す。
var num int = 10
var pointer *int = &num
この pointer を出力すると、当然 num
のメモリのアドレス情報が出力される。
fmt.Println(pointer) // 0x14000104020
ポインタ型変数の中身へアクセスするにはポインタ変数名の前に *
をつける。
fmt.Println(pointer) // 0x14000104020
fmt.Println(*pointer) // 10
このように、ポインタ型の変数が指す実際の値にアクセスする操作のことを「デリファレンス」という。
構造体系 そのいち
Go では struct でオブジェクト指向における class を表現できる。
type Person struct {
name string
age int
}
構造体の初期化方法はいくつかある。
ひとつめ。
変数定義後に設定する方法。
var person Person
person.name = "shion"
person.age = 10
ふたつめ。
{}
で値を渡す方法。
person := Person{
"shion", 10,
}
ふたつめに関しては、フィールド名も指定できる。
person := Person{
name: "shion", age: 10,
}
みっつめ。
初期化関数(コンストラクタ)を用意する方法。
func newPerson(name string, age int) *Person {
return &Person{name: name, age: age}
}
みっつめの方法を理解するには、前述したポインタ系の知識が必要になる。
newPerson
関数は、返り値に *Person
とあるので「Person型のメモリのアドレス情報を返す」ということがわかる。
実際、&
を使って Person 構造体のメモリのアドレス情報を返している。
構造体系 そのに
Go では struct でオブジェクト指向における class を表現できるというのは前述したとおりだ。
つまり、メソッドも定義できる。
メソッドは以下のように定義する。
func (<レシーバ引数>) <関数名>([引数]) [戻り値の型] {
[関数の本体]
}
先ほどの Person 構造体に、自己紹介するメソッドを追加してみる。
自己紹介メソッドは以下のように定義できる。
func (p Person) introduce(greetings string) string {
return fmt.Sprintf("%s! My name is %s.", greetings, p.name)
}