スキップしてメイン コンテンツに移動

Goメソッド入門:値とポインタ

Goメソッド入門:値とポインタ

Go初心者にとってのメソッドとは

Go言語は関数型の特徴を持ちながら、構造体に対してメソッドを定義できる点が魅力です。メソッドは関数と同じ構文を持ちますが、レシーバという特殊なパラメータを持つことで、特定の型に紐付けられます。Go初心者が最初に直面する疑問は「メソッドと関数の違いは何か?」です。実際には、メソッドはレシーバを持つ関数であり、レシーバがあることで呼び出し時に自動的に対象オブジェクトが渡されます。

レシーバの種類: 値レシーバとポインタレシーバ

レシーバには2種類あります。値レシーバは構造体のコピーを受け取り、変更しても元の値は変わりません。ポインタレシーバは構造体へのポインタを受け取り、呼び出し元のデータを直接変更できます。以下に簡単な例を示します。

type Counter struct {
    value int
}

func (c Counter) Increment() {
    c.value++ // 値レシーバなのでコピーに対して増やすだけ
}

func (c *Counter) Decrement() {
    c.value-- // ポインタレシーバで実際の値を減らす
}

値レシーバは軽量で安全ですが、状態を変更したい場合はポインタレシーバを選択します。

メソッド定義と構造体メソッドの書き方

メソッドは次のように定義します。

func (receiver Type) MethodName(params) returnType {
    // 実装
}

ここで「receiver」はレシーバで、型名の前に任意の変数名を付けます。構造体メソッドは構造体型に対して定義され、オブジェクト指向的な振る舞いを実現します。例えば、以下のように書くと、Person構造体に対して名前を取得するメソッドができます。

type Person struct {
    Name string
    Age  int
}

func (p Person) GetName() string {
    return p.Name
}

このようにメソッド定義を行うことで、構造体に機能を追加し、コードを整理できます。

オブジェクト指向的な関連付けと実践例

Goはクラスベースのオブジェクト指向ではありませんが、構造体とメソッドを組み合わせることでオブジェクト指向的な設計が可能です。関連付け(association)は、ある構造体が別の構造体をフィールドとして持つことで実現します。以下は簡単な例です。

type Engine struct {
    HorsePower int
}

type Car struct {
    Brand  string
    Engine Engine // Engineへの関連付け
}

func (c Car) Start() {
    fmt.Printf("%s engine starts with %d HP\n", c.Brand, c.Engine.HorsePower)
}

この例では、CarEngineを持つことで、車とエンジンの関連付けを表現しています。メソッドを使うことで、オブジェクト指向的な振る舞いを簡潔に記述できます。

この記事はAIによって作成されました。

コメント