第7章 関数

Go言語における「関数」は、特定のタスクを実行するためのコードのブロックです。関数は引数を取り、処理を実行した後、結果を返すことができます。以下にGo言語での関数の使用例をいくつか示します。


基本的な関数の定義

ここで、functionNameは関数の名前、parametersは関数に渡される引数のリスト、returnTypeは関数が返す値の型です。

func functionName(parameters) returnType {
    // 関数の本体
}


具体的な例
// パラメータなし、戻り値なしの関数
func sayHello() {
    fmt.Println("Hello!")
}

// パラメータありの関数
func add(x int, y int) int {
    return x + y
}

// 同じ型のパラメータは省略形で書くことができます
func add(x, y int) int {
    return x + y
}

// 複数の戻り値を持つ関数
func swap(x, y string) (string, string) {
    return y, x
}

// 名前付き戻り値
func divide(dividend, divisor int) (quotient, remainder int) {
    quotient = dividend / divisor
    remainder = dividend % divisor
    return
}



基本的な関数の呼び出し

result := add(5, 3)
fmt.Println(result) // 出力: 8


無名関数(ラムダ)

無名関数は、funcキーワードに続けて引数リストと関数の本体を記述することで作成されます。

package main

import "fmt"

func main() {
    // 無名関数の定義と即時実行
    func(message string) {
        fmt.Println(message)
    }("こんにちは、Go!")

    // 変数への無名関数の割り当て
    greet := func(message string) {
        fmt.Println(message)
    }
    greet("こんにちは、Go!")
}


クロージャ

無名関数はクロージャを作成するためにも使用されます。クロージャは、それが作成されたスコープの変数にアクセスできる関数です。

package main

import "fmt"

func main() {
    counter := 0
    increment := func() int {
        counter++
        return counter
    }

    fmt.Println(increment()) // 出力: 1
    fmt.Println(increment()) // 出力: 2
}


高階関数

高階関数とは、他の関数を引数として受け取るか、あるいは関数を戻り値として返す関数のことを指します。これにより、関数をより柔軟に扱い、動的な振る舞いをプログラムに組み込むことができます。

package main

import (
    "fmt"
    "strings"
)

// 高階関数:関数を引数として受け取る
func processText(text string, processor func(string) string) string {
    return processor(text)
}

// 高階関数:関数を戻り値として返す
func sequenceGenerator(start int) func() int {
    i := start
    return func() int {
        i++
        return i
    }
}

func main() {
    input := "Hello, World!"
    
    // 高階関数を使用して文字列を大文字に変換
    result := processText(input, strings.ToUpper)
    fmt.Println(result) // 出力: HELLO, WORLD!

    // 高階関数を使用して文字列を小文字に変換
    result = processText(input, strings.ToLower)
    fmt.Println(result) // 出力: hello, world!

    nextInt := sequenceGenerator(10)

    fmt.Println(nextInt()) // 出力: 11
    fmt.Println(nextInt()) // 出力: 12

    newInts := sequenceGenerator(20)
    fmt.Println(newInts()) // 出力: 21

}


練習問題1.

整数2つを引数として受け取り、それらの積を返す関数 multiplyを作成し、実行して結果を出力してください。

package main

import "fmt"

// ここに multiply 関数を定義

func main() {
    result := multiply(4, 5)
    fmt.Println("結果:", result) // 出力: 結果: 20
}


練習問題2.

2つの整数を引数として受け取り、その和と差を返す関数addAndSubtractを作成してください。この関数は2つの整数を返す必要があります。

package main

import "fmt"

// ここに addAndSubtract 関数を定義

func main() {
    sum, diff := addAndSubtract(10, 5)
    fmt.Println("和:", sum, "差:", diff) // 出力: 和: 15 差: 5
}


練習問題3.

引数として関数を1つ受け取り、整数xを引数の関数に適用してその結果を返す高階関数applyFunctionを作成しなさい。テストとして、整数を2倍にする簡単な関数を引数として渡し、結果を出力してください。

package main

import "fmt"

// ここに applyFunction を定義

func main() {
    double := func(x int) int {
        return x * 2
    }

    result := applyFunction(double, 5)
    fmt.Println("結果:", result) // 出力: 結果: 10
}