Go超入門コース#12 関数

はじめに

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

関数とは?

まず、関数について説明します。
関数とは、いろいろな「処理」をまとめて1つにしたものです。
なぜ関数があるのでしょうか?
料理で例えてみます。
例えば、いつも作るカレーがあるとします。
そのレシピを料理ロボットに記憶してもらいます。
またカレーが食べたくなったときに、
ボタン1つで作れる。
しかも、その料理ロボットは、自分も使えるし、家族も使える。
それが料理ロボットが関数なのです。
関数の便利なところは色々あるのですが、3つあげてみます。
同じものを2回書く必要がない
1行で使い回しができる
関数の中のコードを理解していなくても他の人も使うことができる
といった便利な点です。

関数の定義方法

関数を作ることを「関数の定義する」といいます。
Goでの関数の定義方法についてみていきましょう。

func 関数名( ) {
実行する処理
}

今まで使っていたmain関数も関数です。
このmain関数以外の関数の定義したい場合も、main関数と同じです。
まず、funcと記述します。
funcの後に関数につける名前、つまり、関数名を記述します
関数名のあとに丸括弧を書きます。
関数に値を渡したい場合は、丸括弧の中に引数の定義をします。
この引数は、関数内で使うことができます。
例えば、関数内にある数字と引数を掛け算することができます。
このように、関数に引数を値を渡すことで関数のできる処理の幅が広がります。
引数という言葉は、関数に引数を渡すといったり、関数が引数を受け取るといったりします。
引数は、何個でも渡すことができるので、必要な分だけカンマで区切って入れることができます。
この引数の書き方としては、あとでコードを書きながらじっくり説明しますが、引数名を書いたあとにスペース、そのあとにデータ型を記述します。
また、引数は、必ず必要と言うわけではなく、省略することができます。
最後に{ }波括弧を書いて、波括弧のなかに実行する処理を書きます。
そして、関数は、引数を受け取ることができる一方、関数は処理結果を返すことができます。
これを戻り値といいます。
return文を使うことで、戻り値として関数の外に値を返すことができます。

関数の宣言と実行

それでは、実際に、コードを書いてみましょう。

package main

import "fmt"

func sayHello() {
        fmt.Println("Hello World!")
}

func main() {
        sayHello()
}

このコードは、文字列の「Hello World」を表示するsay_helloという関数を定義するものです。
まずは func、関数名を書きましょう。
関数名は、メッセージを表示させるのでsay_hello関数としました。
今回、引数はないので丸括弧のみを書きます。
波括弧を書いて、実行する処理「fmt.Println(“Hello World”);」を書きます。
これでsay_hello関数を定義は完了です。
関数を実行するには、関数名、丸括弧で実行できます。
main関数内に、関数名のsay_helloに引数なしの丸括弧を記述します。
これで「Hello World」が表示されるはずです。
実行してみましょう。
「Hello World」を表示することができました。

package main
import "fmt"

func sayHello() {
    fmt.Println("Hello World!")
}

func main() {
    sayHello()
    sayHello()
    sayHello()
}

定義した関数は何度でも呼び出すことができます。
3回、say_helloを記述しましょう。
「Hello World」は3回表示されるはずです。
実行してみましょう。
「Hello World」を3回表示することができました。

package main

import "fmt"

func sayHello(greeting string) {
        fmt.Println(greeting)
}

func main() {
        sayHello("Good morning")
}

次に引数ありの変数をみていきましょう。
引数名は、挨拶と言う意味のgreetingとしましょう。
そして受け取った引数をprintlnで表示させましょう。
前は文字列を表示させていたので、printlnの中はダブルクオテーションで括っていましたが、今回は変数を表示させるので、ダブルクオテーションはいりません。
では、main関数のsay_helloの引数に、ダブルクオテーションで「Good morning」を渡してみましょう。
実行してみます。
Good morningが表示されました。

package main

import "fmt"

func sayHello(greeting string) {
        fmt.Println(greeting)
}

func main() {
        sayHello("Good evening")
}

「Good evening」を渡してみましょう。
実行してみます。
Good eveningが表示されました。

package main

import "fmt"

func cal(x int) {
        fmt.Println(x * 3)
}

func main() {
        cal(6)
}

今度は、関数に数値を渡して、関数内で計算と表示をさせてみます。
関数名は、計算をさせるので、計算という意味のcalculateの前3文字をとったcalという関数を作ってみます。
引数名はxとしましょう。数値型なので、int型を記述。
その引数を関数内で掛け算してみましょう。
xかける3をPrintlnで表示させてみます。
実行してみます。
18が表示されました。

package main

import "fmt"

func cal(x int, y int) {
        fmt.Println(x / y)
}

func main() {
        cal(6, 3)
}

引数を2つにしてみましょう。
引数が2つの場合、カンマで区切れば良いです。
yという引数を定義して、これも数値型としましょう。
x割るyとして、これを表示させてみましょう。
xに6、yに3を渡します。
実行してみましょう。
2となり、予想通りの結果となりました。

package main

import "fmt"

func cal(x, y int) {
        fmt.Println(x / y)
}

func main() {
        cal(6, 3)
}

同じデータ型の場合、このように省略することができます。
xとyは数値型という意味です。

package main

import "fmt"

func cal(x, y int) int {
        return (x / y)
}

func main() {
        result := cal(6, 3)
        fmt.Println(result)
}

次に戻り値がある場合の関数をみていきたいと思います。
戻り値がある場合は、引数の右に、戻り値のデータ型を記述します。
例えば、先ほどやったx/yを返したい返したい場合、これは数値型なのでintを記述します。
そして、Printlnではなく、returnを記述します。
main関数内で実行したcal関数を受け取るために、実行結果をresultという変数に代入しましょう。
そして、resultを表示させてみます。
実行してみます。
2が表示されました。

package main

import "fmt"

func cal(x, y int) (int, int) {
        return (x / y), (x * y)
}

func main() {
        result01, result02 := cal(6, 3)
        fmt.Println(result01, result02)
}

次に、戻り値が2つある場合をみていきましょう。
戻り値が2つの場合は、戻り値のところに丸括弧をして、カンマで区切ればよいです。
戻り値は2つとなりますので、代入する変数も2つにします。result01とresult02としましょう。
表示もさせてみます。
6割る3の答えの2と、6かける3の答えの18が表示されるはずです。
実行してみましょう。
予想通りの結果となりました。

package main

import "fmt"

func cal(x, y int) (int, int) {
        a := x / y
        b := x * y

        return a, b
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}

また、計算結果は、このようにcal内の変数に代入してから返すことができます。
例えば、x割るyをaという変数に代入、xかけるyをbという変数に代入して返す場合です。
cal関数に渡す値を変えてみましょう。
実行してみます。
2と50が返ってきました。

package main

import "fmt"

func cal(x, y int) (a int,b int) {
        a = x / y
        b = x * y

        return a, b
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}

関数の戻り値は、cal関数の波括弧の外で宣言することができます。
そのため、宣言と同時に代入する「:=」ではなく、単純に「=」だけでよくなります。
実行してみましょう。
2と50が返ってきました。

package main

import "fmt"

func cal(x, y int) (a int,b int) {
        a = x / y
        b = x * y

        return
}

func main() {
        result01, result02 := cal(10, 5)
        fmt.Println(result01, result02)
}

また、ここで戻り値を宣言しているため、returnのあとの記述も不要です。
このようにreturnのうしろが不要です。
実行してみます。
2と50が返ってきました。

package main

import "fmt"

func sayHello() {
        fmt.Println("Hello World!")
}

func main() {
        sayHello()
}

関数式

関数を変数に代入することができます。
一番最初の挨拶を表示させるコードでみていきましょう。
先ほどのコードはこうでしたよね。
このsayHello関数を変数に代入することができます。
関数をhelloという変数に代入してみましょう。

package main
import "fmt"

func main() {
    hello := func (greeting string) {
        fmt.Println(greeting)
    }

    hello("Good morning")
}

helloという変数に関数を代入します。
funcのあとの関数名は省略できます。
その後の記述は、通常の関数の定義方法と同じです。
実行方法は、関数のあとに丸括弧です。丸括弧の中に引数を記述します。
実行してみます。
Good morningが表示されました。
このようにfuncのあとに関数名がないです。
このような関数を無名関数といいます。

package main
import "fmt"

func main() {
    func (greeting string) {
        fmt.Println(greeting)
    }("Good morning")
}

この無名関数は、そのまま引数を渡して実行することができます。
まずhelloを消します。
無名関数のあとに、すぐに丸括弧で引数を与えます。
引数は、Good eveningとしましょう。
引数は、Good eveningが表示されました。
レッスンは以上となります。

確認問題

それでは確認問題です。
calという関数を作り、10と5の引数を渡します。
足し算の結果を変数に代入して、結果を返してください。
戻り値は、cal関数の波括弧の外で宣言してください。
そして、計算結果をmain関数内のPrintlnで表示させてみてください。
動画をストップして記述してみてください。
それでは正解です。
まず、calという関数を作ります。
私は、引数はxとyとしました。
確認問題は、戻り値は、cal関数の波括弧の外で宣言するので、ここにrスペースintと記述しました。
丸括弧を忘れないようにしましょう。
r = x+yの部分は、宣言がおわっているため、コロンイコールではなく、イコールのみでよいです。
戻り値は宣言しているため、returnのあとは省略しました。
これをresultという変数に代入して、その変数を表示させます。
実行してみましょう。
15が表示されました。
これで関数のレッスンは終わりです。
お疲れ様でした!

package main

import "fmt"

func cal(x, y int) (r int) {
        r = x + y
        return
}

func main() {
        result := cal(10, 5)
        fmt.Println(result)
}