仕事でGolangを使うことになりそうなので、腰を据えて学ぶことにしました。
今まで、Rubyで開発していたのでポインタの操作は久しぶりだったので少しGolangを触って学んだことを整理しました。
同じような背景で、Golangを学び始めた方がポインタについての記憶を思い出す一助になればと記事にしました。
何か間違いなどがあれば気軽にご指摘くださいませ。
ポインタとは?
ポインタとはアドレスを格納した変数のこと。
利用される場面は値渡しではなく参照渡しをして、その値自体を関数内で変更する際。
package main
import (
"fmt"
)
type Employee struct {
ID int
Name string
Salary int
}
func main() {
var employee Employee = Employee{
ID: 1,
Name: "John",
Salary: 300,
}
fmt.Println(employee.Salary) // => 300
// 構造体をそのまま渡すと値がコピーされて渡される(値渡しされる)ので更新結果が反映されない
promete(&employee)
fmt.Println(employee.Salary) // => 1300
}
func promote(pointer *Employee) {
pointer.Salary += 1000
}
ポインタの基本操作
変数に対する操作
&値
: 値のアドレスを持つポインタ
*ポインタ
: ポインタに格納されるアドレス上の値
型定義
*型
: その型の値を指すポインタ
employee := Employee{ID: 2}
// employeeを格納するポインタ
fmt.Println(&employee) // => &{2 0}
// employeeを格納するアドレスの指す値(つまりemployee)
fmt.Println(*&employee) // => {2 0}
// employeeを格納するアドレスを格納する変数(ポインタ)
var pointer *Employee = &employee
// ポインタが指すアドレス上の変数
fmt.Println(*pointer) // => {2 0}
// ポインタは変数なのでそのアドレスも取得できる
fmt.Println(&pointer) // 0xc42000c030
Tips
- 構造体のポインタからそのフィールドに直接アクセスできる
- ポインタの指す値にアクセスする時は、優先順位に気をつける
func promote(pointer *Employee) {
// ⑴ 構造体のポインタからそのフィールドに直接アクセスできる
pointer.salary += 1000
// ⑵ ポインタから値へのアクセス(*)よりフォールドへのアクセスの方が優先度が高いので注意
fmt.Println((*pointer).salary) // => 1300
// empoloyee.salaryの値(int型)をポインタとして値を取得しようとしてエラーになる
fmt.Println(*pointer.salary) // => invalid indirect of pointer.Salary (type int)
}