無名関数とは、関数名を定義する必要のない関数の実装方法を指し、関数名のない関数宣言と関数本体で構成されます。以下、無名関数の定義と使い方について詳しく説明します。
無名関数を定義する
無名関数の定義形式は以下のとおりです。
func(parameter list)(返回参数列表){
コード
}
匿名関数定義は、名前のない通常の関数定義です。
1) 定義時に無名関数を呼び出す
匿名関数は宣言後に呼び出すことができます。次に例を示します。
func(data int) {
fmt.Println("こんにちは", data)
}(100)
3 行目の}
の後の(100)
に注目してください。これは、匿名関数を呼び出してパラメータを 100 として渡すことを意味します。
2) 無名関数を変数に代入します
たとえば、次のような匿名関数を割り当てることができます。
f := func(data int) {
fmt.Println("hello", data)
}
f(100)
匿名関数には幅広い用途があり、それ自体が一種の値であり、コールバック関数や操作のカプセル化を実装するためにさまざまなコンテナに便利に格納できます。
匿名関数はコールバック関数として使用されます
次のコードは、スライスに対するトラバーサル操作を実装します。トラバーサル内の各要素にアクセスする操作は、匿名関数を使用して実装されます。ユーザーは、さまざまな匿名関数本体を渡して、要素に対するさまざまなトラバーサル操作を実装できます。コードは次のとおりです:
package main
import (
"fmt"
)
// スライスの各要素をループし、指定された関数で要素にアクセスする
func visit(list []int, f func(int)) {
for _, v := range list {
f(v)
}
}
func main() {
// 無名関数を使用してスライスの内容を印刷する
visit([]int{1, 2, 3, 4}, func(v int) {
fmt.Println(v)
})
}
コードの説明は次のとおりです。
- 行 8 では、visit() 関数を使用して、トラバーサル プロセス全体をカプセル化しています。トラバーサル中にスライス値を取得したい場合は、コールバック パラメータを visit() に渡すだけです。
- 18 行目では、整数スライス []int{1,2,3,4} を準備し、それをトラバーサル データとして visit() 関数に渡します。
- 行 19 ~ 20 は、走査された各値を出力する機能を持つ無名関数を定義しています。
コールバック関数としての匿名関数の設計は Go 言語システム パッケージでも一般的であり、strings パッケージにも同様の設計があります。コードは次のとおりです。
func TrimFunc(s string, f func(rune) bool) string {
return TrimRightFunc(TrimLeftFunc(s, f), f)
}
次のコードは、匿名関数をマップのキー値として使用し、コマンド ライン パラメーターを通じて匿名関数を動的に呼び出します。
package main
import (
"flag"
"fmt"
)
var skillParam = flag.String("skill", "", "パフォームするスキル")
func main(){
flag.Parse()
var skill = map[string]func(){
"fire": func() {
fmt.Println("chicken fire")
},
"run": func() {
fmt.Println("soldier run")
},
"fly": func() {
fmt.Println("angle fly")
},
}
if f, ok := skill[*skillParam]; ok {
f()
} else {
fmt.Println("スキルが見つかりません")
}
}
コードの説明は次のとおりです。
- 8行目はコマンドラインパラメータのスキルを定義しており、コマンドラインから –skill を入力して
=
の後の文字列をskillParamポインタ変数に渡します。 - 行 12 はコマンド ライン パラメータを解析します。解析が完了すると、skillParam ポインタ変数はコマンド ラインに渡された値を指します。
- 14 行目は、文字列から func() へのマップを定義し、マップを埋めます。
- 15 行目から 23 行目はマップのキーと値のペアを初期化し、値は匿名関数です。
- 26 行目では、skillParam は *string 型のポインター変数です。*skillParam を使用してコマンド ラインから渡された値を取得し、コマンド ライン パラメーターで指定された文字列に対応する関数をマップで検索します。
- 29行目、マップ定義にこのパラメータがあればそれが呼び出され、それ以外の場合は「スキルが見つかりません」と出力されます。
コードを実行すると、結果は次のようになります。
PS D:\code> go run main.go --skill=fly
chicken fly
PS D:\code> go run main.go --skill=run
soldier run