関数(複数戻り値, 名前付き戻り値, 可変長引数, 高階関数, 再帰関数)

Goによる関数の実装方法を確認します。「複数戻り値」「名前付き戻り値」「可変長引数」「高階関数」「再帰関数」といった内容を実装して動作確認していきます。

基本

引数と戻り値

int型の引数を受け取り、string型の値を返す関数の例です。

package main

import "fmt"

func func1(x int) string {
	return fmt.Sprint("hello world '", x, "'.")
}

func main() {
	fmt.Println(func1(1234))
	fmt.Println(func1(5678))
}
hello world '1234'.
hello world '5678'.

複数戻り値

package main

import "fmt"

func func2(x, y int) (int, int) {
	return x + y, x - y
}

func main() {
	x, y := func2(10, 5)
	fmt.Println(x)
	fmt.Println(y)
}
15
5

名前付き戻り値

以下例では、add sub という名前付き戻り値で値を返しています。

package main

import "fmt"

func func3(x, y int) (add, sub int) {
	add = x + y
	sub = x - y
	return
}

func main() {
	x, y := func3(10, 5)
	fmt.Println(x)
	fmt.Println(y)
}
15
5

可変長引数

... の記法で可変長引数を実装できます。

package main

import "fmt"

func func4(i ...int) int {
	fmt.Println("-----------------")
	fmt.Println(i)
	sum := 0
	for _, v := range i {
		sum += v
	}
	return sum
}

func main() {
	fmt.Println(func4())
	fmt.Println(func4(1))
	fmt.Println(func4(1, 2))
	fmt.Println(func4(1, 2, 3))

	s := []int{1, 2, 3, 4}
	fmt.Println(func4(s...))

}
-----------------
[]
0
-----------------
[1]
1
-----------------
[1 2]
3
-----------------
[1 2 3]
6
-----------------
[1 2 3 4]
10

一歩進んだ使い方

高階関数 ( 関数に関数を渡す )

以下、高階関数(他の関数を引数として受け取れる関数)の実装例です。

package main

import "fmt"

func add(x, y int) int {
	return x + y
}

func sub(x, y int) int {
	return x - y
}

func ope(
	x, y int,
	cb func(int, int) int,
) int {
	return cb(x, y) + 10
}

func main() {
	fmt.Println(ope(10, 5, add))
	fmt.Println(ope(10, 5, sub))
}
25
15

再帰関数

再帰関数で階乗を求めてみます。

package main

import "fmt"

func factorial(i int) int {
	if i < 0 {
		return -1
	} else if i == 0 {
		return 1
	} else {
		return i * factorial(i-1)
	}
}

func main() {
	fmt.Println(factorial(-10))
	fmt.Println(factorial(0))
	fmt.Println(factorial(4))
}
-1
1
24

関数を要素に持つスライス

package main

import "fmt"

func main() {
	var tasks = []func(int) string{
		func(i int) string { return fmt.Sprintf("aaa %d", i) },
		func(i int) string { return fmt.Sprintf("bbb %d", i) },
		func(i int) string { return fmt.Sprintf("ccc %d", i) },
	}

	for i, task := range tasks {
		fmt.Println(task(i))
	}
}
aaa 0
bbb 1
ccc 2

即時関数

package main

import "fmt"

func main() {
	func(m string) {
		fmt.Println(m)
	}("Hello World")
}
Hello World

参考