← Go コース
33. 値レシーバとポインタレシーバの違い
レシーバには値レシーバ (p Point) とポインタレシーバ (p *Point) の二種類があります。値レシーバはメソッド呼び出し時にレシーバがコピーされるため、メソッドの中でフィールドを書き換えても元の値には反映されません。一方ポインタレシーバは元の値を指すので、フィールドを書き換えるとそのまま呼び出し元に反映されます。
したがって、レシーバの状態を変更するメソッドにはポインタレシーバを使います。また大きな構造体ではコピーを避けるためにポインタレシーバが効率的です。下の例では、値レシーバの ScaleByValue は元を変えられず、ポインタレシーバの Scale だけが元の値を書き換えられることが確認できます。
便利なことに、Go は p が値でもポインタでも、必要に応じて自動で &p や *p に変換してメソッドを呼んでくれます。そのため呼び出し側の書き方はほとんど気にせずに済みます。設計の指針としては、ある型にポインタレシーバのメソッドがあるなら、混乱を避けるためその型のメソッドはすべてポインタレシーバで統一するのが一般的です。
▶ サンプルコードを実行してみよう(自由に書き換えてOK)
Go