メソッドとレシーバ

Go言語における「メソッドとレシーバ」は、構造体と関数を組み合わせてオブジェクト指向的な振る舞いを実現するための仕組みです。Goは純粋なオブジェクト指向言語ではありませんが、この機能により、構造体に対してメソッドを定義し、インスタンスに振る舞いを持たせることができます。


1. メソッドとは何か

**メソッド(method)**とは、特定の型(主に構造体)に属する関数のことです。関数と似ていますが、メソッドは「レシーバ(receiver)」を持つ点が異なります。

go
func (r ReceiverType) MethodName(params...) returnType { // メソッドの処理 }

2. レシーバとは何か

**レシーバ(receiver)**は、メソッドが属する型のインスタンスを表します。C++やJavaでいうところの「this」に近い役割を持ちます。

レシーバの型には以下の2種類があります:

  • 値レシーバ(value receiver)
    func (r StructType)
    → レシーバのコピーが渡され、元の構造体の内容は変更されない。

  • ポインタレシーバ(pointer receiver)
    func (r *StructType)
    → レシーバのアドレスが渡され、元の構造体の内容を変更できる。


3. 例:構造体とメソッドの定義

go
package main import "fmt" type Rectangle struct { Width float64 Height float64 } // 値レシーバのメソッド(元のデータは変更されない) func (r Rectangle) Area() float64 { return r.Width * r.Height } // ポインタレシーバのメソッド(元のデータを変更できる) func (r *Rectangle) Resize(newWidth, newHeight float64) { r.Width = newWidth r.Height = newHeight } func main() { rect := Rectangle{Width: 10, Height: 5} fmt.Println("面積:", rect.Area()) rect.Resize(20, 10) fmt.Println("新しい面積:", rect.Area()) }

4. 値レシーバとポインタレシーバの使い分け

条件 推奨されるレシーバの型
構造体が小さく、変更不要 値レシーバ
構造体が大きい、または変更したい ポインタレシーバ

5. メソッドは構造体以外にも定義可能

Goでは、**構造体だけでなく任意の型(ただし、型定義されたもの)**にもメソッドを定義できます。

go
type MyInt int func (m MyInt) Double() int { return int(m) * 2 }

まとめ

  • メソッドは特定の型に属する関数。

  • レシーバによってそのメソッドがどのインスタンスに属するかが決まる。

  • 値レシーバはコピーされ、ポインタレシーバは元の値を変更できる。

  • Goは構造体とメソッドを通じてオブジェクト指向的な設計が可能。

生成日:2025/05/03