[box class="blue_box" title="☑本記事の内容"]
- クロージャー
- 可変長引数
[/box]
参考資料:現役シリコンバレーエンジニアが教えるGo入門 + 応用でビットコインのシストレFintechアプリの開発
[box class="glay_box" title="Contents"]
[/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]