0Pricing
Go Academy · レッスン

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フィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 関数の基本とシグネチャ
  2. 複数の戻り値
  3. 可変長引数関数
  4. defer、無名関数、クロージャ
← Go Academyに戻る