【Go言語 超入門コース】14.メソッド|Goのメソッドは、他の言語のメソッドとは違っています【プログラミング初心者向け入門講座】

はじめに

こんにちは。キノコードです。
「Go超入門コース#14 メソッド」について説明します。

メソッドとは?

メソッドとは、構造体などの特定の型に関連づけられた関数のことです。
メソッドといっても、他のプログラミング言語にあるメソッドとは異なります
例えば、Pythonなどのプログラミング言語のメソッドは、クラスの中に記述されたものです。
しかし、そもそもGo言語にはクラスの概念がありません。
また、メソッドは、構造体に関連づけられた関数ですが、構造体の中に記述するわけでもありません。
いずれにしても、Go言語のメソッドは、他の言語にあるメソッドとは異なります。

メソッドの定義方法

package main

type Student struct {
        name          string
        math, english float64
}

func main() {

}

メソッドの定義の方法を、コードを書いて見ていきましょう
レッスン13でやった構造体をまず記述しましょう。
構造体名はStudentとして、生徒の名前を格納するnameというフィールドと、数学と英語の点数を格納するmathとenglishというフィールドを定義します。
次にメソッドを記述していきます。

package main

type Student struct {
        name          string
        math, english float64
}

func avg() {
}

func main() {

}

メソッドは、関数の定義と似ています。
まずfuncとメソッド名。そして、丸括弧です。
引数がある場合、丸括弧に記述します。今回は引数なしとしましょう。
ここまでは関数と同じです。
メソッドの最初の説明で、メソッドは構造体などの特定の型に関連づけられた関数だと説明しました。
構造体と関連づける記述をしましょう。
funcとメソッドの間に丸括弧。丸括弧の中に、変数名、半角スペース、関連づける構造体名と記述します。

package main

type Student struct {
        name          string
        math, english float64
}

func (s Student) avg() {
}

func main() {
}

この記述をすることにより、メソッドの中で、フィールドの値を使うなどができるようになります。
具体的には、このsを使って、構造体のフィールドを使うことができます。
やってみましょう。

package main

type Student struct {
        name          string
        math, english float64
}

func (s Student) avg() {
        fmt.Println((s.name,(s.math + s.english) / 2)
}

func main() {

}

使い方は、変数名ドット、フィールド名でよいです。nameを表示させてみましょう。s.nameと記述します。
これをPrintlnで表示させてみましょう。
あわせて、フィールドのmathとenglishも使ってみましょう。
Printlnで、mathとenglishを足して、割る 2。つまり、数学と英語の平均点を算出してみましょう。
これでフィールドとメソッドの定義はおわりです。
ちなみに、ここの部分(s Student)をレシーバといいます。
それではメソッドを使ってみましょう。

package main

import "fmt"

type Student struct {
        name          string
        math, english float64
}

func (s Student) avg() {
        fmt.Println(s.name, (s.math+s.english)/2)
}

func main() {
        a001 := Student{"sato", 80, 70}
        a001.avg()
}

satoさんは、aという学級の出席番号001番だったとします。
a001に構造体を初期化をして代入しましょう。
初期化と同時に値を渡します。
このsatoさんは、数学を80点、英語を70点をとったとします。
したがって、a001にコロン、イコールを書いて、構造体名。波括弧の中に引数を記述します。
これで構造体を使えるようになりました。
メソッドの使い方は、a001ドット、メソッド名となります。
実行してみます。
satoと75が表示されました。

function say_hello() {
  console.log("Hello World");
}
say_hello();
say_hello();package main

import "fmt"

type Student struct {
        name string
}

func (s Student) avg(math, english float64) {
        fmt.Println((math + english) / 2)
}

func main() {
        a001 := Student{"sato"}
        a001.avg(80, 70)
}
say_hello();

メソッドに引数を渡す方法も試してみましょう。
メソッドの定義の記述の部分をみてみます。avgのあとの丸括弧に、渡す引数を記述すればよいです。
mathとenglishをfloatで渡す記述をしましょう。
メソッドを呼び出す部分は、引数を記述すれば良いです。
つまり、80と70を記述します。
実行してみましょう。
75が表示されました。

package main

import "fmt"

type Student struct {
        name string
}

func (s Student) avg(math, english float64) float64 {
        return (math + english) / 2
}

func main() {
        a001 := Student{"sato"}
        fmt.Println(a001.avg(80, 70))
}

次に戻り値があるメソッドをみていきましょう。
戻り値があるメソッドの定義の方法は、戻り値がある関数の定義の方法と同じです。
メソッドの引数を記述する丸括弧のあとに、戻り値のデータ型を記述すればよいです。
floatを記述しましょう。
また、Pringlnを書いていたところにreturnを記述しましょう。
これで、メソッドを呼び出すところをプリントで表示させてみましょう。
実行してみます。
75が表示されました。

package main

import "fmt"

type Student struct {
        name string
}

func (s Student) avg(math, english float64) (avgResult float64) {
        avgResult = (math + english) / 2
        return
}

func main() {
        a001 := Student{"sato"}
        fmt.Println(a001.avg(80, 70))
}

レッスン12関数で説明したように、戻り値の変数を先に宣言して、returnのところの変数を省略することができます。
メソッド名のあとに丸括弧。丸括弧の中に戻り値の変数とデータ型を記述します。
戻り値の変数名をavgResultとしましょう。
平均の結果をavgResultに代入。
returnの後ろは省略します。
実行してみます。
75が返ってきました。

確認問題

確認問題です。
ここでは、ユーザーの名前を保持する構造体と、BMIを計算するメソッドを定義していきたいと思います。
Userという名前の構造体、nameという名前を格納するフィールドを定義。
次に、BMIを計算するメソッドを定義します。メソッド名は、calという名前。このメソッドには、weightとheightという引数を渡します。
BMIの計算は、体重÷身長÷身長×10000でできます。
その計算結果を、resultという変数に格納して、結果を返します。
皆さんの名前とともに構造体を初期化。
名前とメソッドの計算結果をプリントラインで表示させてください。
それでは動画をいったん止めて、記述してみて下さい。
それでは正解です。

package main

import "fmt"

type User struct {
        name string
}

func (b User) cal(weight, height float64) (result float64) {
        result = weight / height / height * 10000
        return
}

func main() {
        user01 := User{name: "kino"}
        fmt.Println(user01.name, user01.Cal(65, 175))
}

Userという名前の構造体、nameという名前を格納するフィールドを定義します。
calというメソッドを定義。このメソッドには、weightとheightという引数を渡します。
体重÷身長÷身長×10000をresultに格納して、returnで返します。
それでは、私の名前のkinoを渡して初期化。
名前と共に、メソッドに体重と身長を渡して実行してみましょう。
名前とbmiの計算結果が返ってきました。