tanke25616429のアウトプット

IT技術の基本を勉強したことをアウトプットします。Linux、Kubernetes、クラウド中心です。百番煎じくらいだけど誰かの役に立てばそれはそれでうれしい。

Go の関数とメソッドの書き方の違い

関数とメソッド

関数もメソッドも、引数を与えるとそれに基づいた計算結果を返却する。プログラム内で何度も登場する処理を共通化して再利用可能なものにしている。ただし、メソッドはオブジェクト指向において使われる言葉である。オブジェクト指向は、関連するデータとメソッド(手続き)を束ねたオブジェクトという概念を規定する。オブジェクト指向のメソッドと比較すると、関数というのは何らかのオブジェクトに属しているものではない。

Goの関数とメソッド

Goでは関数とメソッドを両方定義し利用できる。

関数

関数は

func 関数名(引数) 戻り値の型 {
  処理
    return 戻り値
}

の形で定義し、main関数の中で

関数名(引数(実際に計算させたい値))

の形で呼び出す。

メソッド

メソッドはオブジェクト指向のものなので、メソッドを使う場合はオブジェクトが必要である。ここでのオブジェクトは構造体(struct)をもとに定義したレシーバである。

まず構造体を定義する。

type 構造体名 struct{ メンバ }

上の構造体定義をベースとして、以下のようにメソッドを定義する。funcで始まるが、関数と違い、すぐそのあとにはカッコが来る。レシーバはメソッドを呼び出される対象である。カッコ内を見るとわかる通りレシーバはあたかも構造体のように定義されている。処理の中身では処理対象の変数はレシーバもしくのメンバとして参照される(レシーバを構造体としてレシーバ.メンバのように扱う)。ここは後程出てくるサンプルを見てもらったほうがイメージがわかりやすい。

func (レシーバ名 定義した構造体名) メソッド名() メソッドの戻り値の型 {
  処理
    return 戻り値
}

メソッドで実際に計算するときは、main関数の中で構造体のインスタンスを定義し*1

構造体インスタンス名 := 構造体名{メンバの具体的な数値}

下記のように計算する。関数をイメージするとカッコ内に数値が入っていないのでどんな値を渡しているかわからないように見えるが、実際にメソッドに渡したい値は構造体を定義したときに決まっているので、それで計算できるわけである。

構造体インスタンス名.メソッド名()

サンプル

2つのint型の数値を加算するプログラム(func-method.go)を考える。以下の例では関数を使ったパターンとメソッドを使ったパターンの両方が記載されている(結果はどちらも同じ)。ただし、Goでは構造体のメンバにメソッドを定義することができないため、メソッドは構造体とは別に定義する。

myaddfuncが関数であり、引数に3,4という数値を与えて結果を計算している。

一方、int型の構造体mystructを定義したのち、Xというレシーバに対し、myaddmethod()というメソッドを定義している。main関数の中でX1という構造体を定義し、構造体のメンバに34を代入してから、X1.myaddmethod()という形で実際の処理を行う。

package main

import "fmt"

// define function
func myaddfunc(a, b int) int {
    return a + b
}

// define struct and method
type mystruct struct{ a, b int }

func (X mystruct) myaddmethod() int {
    return X.a + X.b
}

// main
func main() {
    // use function
    fmt.Println(myaddfunc(3, 4))

    // use method
    X1 := mystruct{3, 4}
    fmt.Println(X1.myaddmethod())
}

計算結果は以下。

$ go run .\func-method.go
7
7

参考にしたもの

it-engineer-info.com

Goの関数とメソッドの違いを解説する | KATUBLO

わわわIT用語辞典 > 違いの分かるピヨピヨ > 「関数」と「メソッド」の違い

【初心者向け!】Javaのメソッド(関数)の使い方

オブジェクト (プログラミング) - Wikipedia

skatsuta.github.io

*1:もちろんvarで宣言してから、メンバを別の式で代入してもよい。