Go 入門

Go言語入門⑥ ~クロージャー・可変長引数~

[box class="blue_box" title="☑本記事の内容"]

  • クロージャー
  • 可変長引数

[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]

  1. クロージャー
  2. 可変長引数

[/box]

クロージャー

[box class="yellow_box" title="✔クロージャーの目次"]

[/box]

基本的なこと

[box class="glay_box"]

  • 関数を数度読み込み、値の変化が起こるようにする

[/box]

package main

import (
	"fmt"
)

func main() {
	x := 0
	increment := func() int {
		x++
		return x
	}
	fmt.Println(increment())
	fmt.Println(increment())
	fmt.Println(increment())
}
(結果)
1
2
3

[box class="glay_box"]

  • main関数の中に入れるとxの書き換えを行ってしまう可能性があるので別の関数で使う
  • その関数内でクローズドしてるからクロージャー

[/box]

package main

import (
	"fmt"
)

func incrementGenerator() func() int {
	x := 0
	return func() int {
		x++
		return x
	}
}

func main() {
	counter := incrementGenerator()
	fmt.Println(counter())
	fmt.Println(counter())
	fmt.Println(counter())
	fmt.Println(counter())
}
(結果)
1
2
3
4

使用例

[box class="glay_box"]

  • 円周の長さを求める式を例とする
  • 値を変えて違う結果を得たいときにクロージャーは使用される
  • クロージャー自体応用編なので「こんなのあったな」くらいの感覚でOK

[/box]

package main

import (
	"fmt"
)

func circleArea(pi float64) func(radius float64) float64 {
	return func(radius float64) float64 {
		return pi * radius * radius
	}
}

func main() {
	c1 := circleArea(3.14)
	fmt.Println(c1(2))
	fmt.Println(c1(3))

	fmt.Println("==========")

	c2 := circleArea(3)
	fmt.Println(c2(2))
	fmt.Println(c2(3))
}
(結果)
12.56
28.259999999999998
==========
12
27

可変長引数

[box class="yellow_box" title="✔可変長引数の目次"]

[/box]

基本的なこと

[box class="glay_box"]

  • 複数の引数を入れる際に使用される
  • 引数を2つに設定した際に3つ入れようとするとエラーになる

[/box]

package main

import (
	"fmt"
)

func foo(param1, param2 int) {
	fmt.Println(param1)
}

func main() {
	foo(10, 20)
	foo(10, 20, 30)
}
(結果)エラー表示
too many arguments in call to foo
	have (number, number, number)
	want (int, int)

[box class="glay_box"]

  • 引数のところを...と追加することで可変長になる

[/box]

package main

import (
	"fmt"
)

func foo(params ...int) {
	fmt.Println(len(params), params)
}

func main() {
	foo()
	foo(10, 20)
	foo(10, 20, 30)
}
(結果)
0 []
2 [10 20]
3 [10 20 30]

スライスを入れる場合

[box class="glay_box"]

  • そのまま入れようとするとエラーになる

[/box]

package main

import (
	"fmt"
)

func foo(params ...int) {
	fmt.Println(len(params), params)
}

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

	foo(s)
}
(結果)エラー表示
cannot use s (type []int) as type int in argument to foo

[box class="glay_box"]

  • スライスの場合は渡す際に...を追加する

[/box]

package main

import (
	"fmt"
)

func foo(params ...int) {
	fmt.Println(len(params), params) 
}

func main() {
	s := []int{1, 2, 3}
	fmt.Println(s)
	foo(s...)
}
(結果)
[1 2 3]
3 [1 2 3]

Go言語入門⑦へ ≫

≪ Go言語入門⑤へ

目次

-Go, 入門