メインコンテンツまでスキップ

Go言語の関数とメソッド

Go言語において、関数 (function)メソッド (method) の主な違いは、メソッドにはレシーバー (receiver) と呼ばれる特定の型に関連付けられた要素がある点です。以下に違いを詳しく説明します。


1. 関数

  • 定義: 関数は特定の型に属さない独立したコードブロック(code block)です。
  • 特徴:
    • レシーバーがありません。
    • 任意の引数を受け取り、値を返します。
  • :
package main

import "fmt"

// 通常の関数
func add(a int, b int) int {
return a + b
}

func main() {
result := add(3, 5) // 関数の呼び出し
fmt.Println(result) // 出力: 8
}

この関数addは特定の型や構造体に関連付けられていない独立した機能です。


2. メソッド

  • 定義: メソッドは、特定の型(通常は構造体)に関連付けられた関数です。
  • 特徴:
    • レシーバー (receiver) を持ちます。
    • レシーバーはメソッドがどの型に属しているかを指定します。
    • 構造体やカスタム型の振る舞い(動作)を定義します。
  • :
package main

import "fmt"

// 構造体の定義
type Person struct {
Name string
Age int
}

// 構造体に関連付けられたメソッド
func (p Person) Greet() {
fmt.Printf("Hello, my name is %s and I am %d years old.\n", p.Name, p.Age)
}

func main() {
p := Person{Name: "Alice", Age: 25}
p.Greet() // メソッドの呼び出し
}

このメソッドGreetPerson型に属しており、構造体のプロパティ(NameAge)を使用して動作します。


3. レシーバーの種類

メソッドのレシーバーには2種類あります。

値レシーバー

  • レシーバーが構造体の値そのものを受け取ります。
  • メソッド内で構造体の フィールド(field) を変更しても、元の値には影響しません。
  • 例:
func (p Person) DisplayName() {
p.Name = "Anonymous" // 値レシーバーのため、元の構造体は影響を受けない
fmt.Println(p.Name)
}

ポインタレシーバー (pointer receiver)

  • レシーバーが構造体のポインタを受け取ります。
  • メソッド内で構造体のフィールドを変更すると、元の値も更新されます。
  • 例:
func (p *Person) UpdateAge(newAge int) {
p.Age = newAge // ポインタレシーバーのため、元の構造体が変更される
}

func main() {
p := Person{Name: "Alice", Age: 25}
p.UpdateAge(30)
fmt.Println(p.Age) // 出力: 30
}

4. 関数とメソッドの主な違いのまとめ

項目関数メソッド
レシーバーなし必須(値またはポインタ)
関連性独立した機能を定義する特定の型に関連付けて振る舞いを定義する
使用例汎用的な処理型や構造体に特化した処理

Goのメソッドはオブジェクト指向的な設計を可能にしますが、Goそのものは完全なオブジェクト指向言語ではありません。関数とメソッドを使い分けることで、簡潔で効率的なコードを記述できます。