defer、無名関数、クロージャ
遅延実行される呼び出しと関数値
「defer、無名関数、クロージャ」はCoddyKit上の無料Go Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはGo Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 Go Academyコースには全4レッスンが含まれています。
defer:遅延実行
defer は、周囲の関数が戻るときに関数呼び出しを実行するよう予約します。通常の return、エラー、panic など、どのような戻り方でも実行されます。
func readFile(path string) {
f, err := os.Open(path)
if err != nil { return }
defer f.Close() // runs when readFile returns
// read from f...
}defer の実行順序
遅延された呼び出しはスタックに積まれ、LIFO(後入れ先出し)の順序で実行されます。
func main() {
defer fmt.Println("third")
defer fmt.Println("second")
defer fmt.Println("first")
// Output: first, second, third
}defer によるクリーンアップ
defer は、リソースが確実に解放されるようにする Go の慣用的な方法です。
- ミューテックスをロックした後にアンロックする
- ファイルを開いた後に閉じる
- データベーストランザクションをコミットまたはロールバックする
- WaitGroup.Add() の後に WaitGroup.Done() を呼び出す
引数を伴う defer
遅延された呼び出しの引数は、実行時ではなく defer が呼び出された直後に評価されます。
x := 10
defer fmt.Println(x) // prints 10, not 20
x = 20
fmt.Println(x) // prints 20無名関数
無名関数(関数リテラル)は、名前を付けずにインラインで定義します。
double := func(n int) int {
return n * 2
}
fmt.Println(double(5)) // 10
// Immediately invoked:
result := func(a, b int) int { return a + b }(3, 4)クロージャ
クロージャとは、周囲のスコープにある変数をキャプチャする関数です。
func makeCounter() func() int {
count := 0
return func() int {
count++
return count
}
}
ctr := makeCounter()
fmt.Println(ctr(), ctr(), ctr()) // 1 2 3ループでのクロージャのキャプチャに関する注意点
クロージャは変数を参照によってキャプチャするため、goroutine のループでよくあるバグの原因になります。
for i := 0; i < 3; i++ {
i := i // create a new variable per iteration
go func() { fmt.Println(i) }()
}名前付き戻り値と defer
遅延関数は名前付き戻り値を変更できます。これはエラーに情報を付加する場合に便利です。
func doWork() (err error) {
defer func() {
if err != nil {
err = fmt.Errorf("doWork: %w", err)
}
}()
return riskyOp()
}クロージャによる関数型パターン
クロージャを使うと、メモ化などの関数型パターンを実現できます。
func memoize(f func(int) int) func(int) int {
cache := map[int]int{}
return func(n int) int {
if v, ok := cache[n]; ok {
return v
}
v := f(n)
cache[n] = v
return v
}
}ミドルウェアとしてのクロージャ
クロージャは、Go の HTTP サーバーでミドルウェアを構築するための基本要素です。ハンドラーをラップして、その前後に処理を追加します。
func withLogging(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Printf("%s %s", r.Method, r.URL)
next(w, r)
}
}簡単な確認
遅延された関数呼び出しの引数は、いつ評価されますか。
まとめ:defer、クロージャ、無名関数
これらの機能によって、Go のコードを表現力豊かで安全なものにできます。
deferは関数終了時のクリーンアップを保証します(LIFO 順)- defer の引数は直ちに評価されます
- 無名関数は変数に代入したり、インラインで呼び出したりできます
- クロージャは周囲の変数を参照によってキャプチャします
- goroutine でのループ変数のキャプチャバグに注意してください
次のコースは、配列、スライス、マップです。
よくある質問
「defer、無名関数、クロージャ」レッスンは無料ですか?
はい。「defer、無名関数、クロージャ」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、Go Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 Go Academyコースには全4レッスンが含まれています。
「defer、無名関数、クロージャ」で何を学びますか?
遅延実行される呼び出しと関数値 ブラウザで直接実行するハンズオンコードでGo Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
Go Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのGo Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。
「defer、無名関数、クロージャ」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このGo Academyレッスンでコードを書いて実行できますか?
はい。すべてのGo Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。
このコースのすべてのレッスン
- 関数の基本とシグネチャ
- 複数の戻り値
- 可変長引数関数
- defer、無名関数、クロージャ