It’s now or never

IT系の技術ブログです。気になったこと、勉強したことを備忘録的にまとめて行きます。

【Go】関数とメソッド

最近Goを勉強し始めました。

関数とメソッドの違い

基本的には次のように考えています。

  • 関数は、一般的な関数(funcから始まる)
  • メソッドは「型」に関連付けられた関数

関数

package main

import "fmt"

// これは関数
func Bark() {
    fmt.Println("Bow wow. Woof woof.")
}

func main() {
  // 関数呼び出し
  Bark()
}

出力

Bow wow. Woof woof.

メソッド

package main

import "fmt"

// 型を一つ定義
type Animal struct{ name string }

// これはメソッド
func (animal Animal) Bark() {
    fmt.Printf("[%v] meow.", animal.name)
}

func main() {
    animal := Animal{"Cat"}
    // メソッド呼び出し
    // 型に対してドット(.)でアクセス
    animal.Bark()
}

出力

[Cat] meow.
  • 変数を宣言して、ドット経由で呼び出せます

定義の違い

メソッドの定義は関数定義のfuncの後ろに(<変数> <型>)が追加されています

関数

func Bark() {

メソッド

func (animal Animal) Bark() {
  • この(<変数> <型>)で定義されている関連する型を「レシーバ(receiver)」と呼びます

オブジェクトの表現

Go言語にはクラスという概念がないため、このメソッドとレシーバ(型)との関連でオブジェクトを表現します
※ 言語仕様としてオブジェクトというものは存在しません

例えば、上記サンプルをJavaで表現すると以下のようになります。

class Animal {
  String name;
  
  void bark() {
      System.out.println("Bow wow. Woof woof.");
  }
}

public class Main {
    public static void main(String[] args) {
        Animal animal = new Animal();
        animal.bark();
    }
}

Javaのオブジェクト思考の概念では、クラスは「属性(フィールド)」(上ではname)と「操作(メソッド)」(上ではbark)で表現されます。
つまり動物(Animal)というオブジェクトは、名前(name)という属性(データ)で構成されていて、吠える(bark)という操作(振る舞い、動作)をするというような考え方です。

Goの場合は、Javaよりも仕様がシンプルで「型(データ)」がまずあります。
そしてそれは何らかの「関数」によって操作されます。
その特定のデータを操作する特別な関数(振る舞い)を「メソッド」と定義しています。

参考


ちょっとずつ言語仕様を理解していけたらと思います。