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() // メソッドの呼び出し
}
このメソッドGreetはPerson型に属しており、構造体のプロパティ(NameやAge)を使用して動作します。
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そのものは完全なオブジェクト指向言語ではありません。関数とメソッドを使い分けることで、簡潔で効率的なコードを記述できます。