Closures

Closure adalah fungsi yang bisa mengakses variabel dari scope di luarnya (outer scope).

Contoh Masalah

Bagaimana cara membuat fungsi yang:

  1. Menyimpan state antar pemanggilan
  2. Membuat counter yang bisa diincrement
  3. Membuat fungsi dengan konfigurasi yang berbeda

Penyelesaian

package main

import "fmt"

// 1. Fungsi yang mengembalikan closure
func createCounter() func() int {
    count := 0
    return func() int {
        count++
        return count
    }
}

// 2. Fungsi dengan parameter yang digunakan dalam closure
func multiplier(factor int) func(int) int {
    return func(x int) int {
        return x * factor
    }
}

// 3. Closure untuk membuat logger
func createLogger(prefix string) func(string) {
    return func(message string) {
        fmt.Printf("[%s] %s\n", prefix, message)
    }
}

func main() {
    // Contoh 1: Counter
    counter1 := createCounter()
    counter2 := createCounter()

    fmt.Println("Counter 1:")
    fmt.Println(counter1()) // 1
    fmt.Println(counter1()) // 2
    fmt.Println(counter1()) // 3

    fmt.Println("\nCounter 2:")
    fmt.Println(counter2()) // 1
    fmt.Println(counter2()) // 2

    // Contoh 2: Multiplier
    double := multiplier(2)
    triple := multiplier(3)

    fmt.Println("\nMultiplier:")
    fmt.Println("Double 5:", double(5)) // 10
    fmt.Println("Triple 5:", triple(5)) // 15

    // Contoh 3: Logger
    infoLogger := createLogger("INFO")
    errorLogger := createLogger("ERROR")

    fmt.Println("\nLogger:")
    infoLogger("Aplikasi dimulai")
    infoLogger("Memproses data")
    errorLogger("Terjadi kesalahan")

    // Contoh 4: Closure dalam loop
    fmt.Println("\nClosure dalam loop:")
    funcs := make([]func(), 3)
    
    // Cara yang benar
    for i := 0; i < 3; i++ {
        i := i // Create new variable in each iteration
        funcs[i] = func() {
            fmt.Printf("Fungsi %d\n", i)
        }
    }

    // Menjalankan fungsi-fungsi
    for _, f := range funcs {
        f()
    }
}

Penjelasan Kode

  1. Closure Dasar

    • Mengakses variabel luar
    • Menyimpan state
    • Setiap instance terpisah
  2. Closure dengan Parameter

    • Membuat fungsi dengan konfigurasi
    • Parameter disimpan dalam closure
  3. Closure dalam Loop

    • Perhatikan variable capture
    • Buat variabel baru dalam loop

Output

Counter 1:
1
2
3

Counter 2:
1
2

Multiplier:
Double 5: 10
Triple 5: 15

Logger:
[INFO] Aplikasi dimulai
[INFO] Memproses data
[ERROR] Terjadi kesalahan

Closure dalam loop:
Fungsi 0
Fungsi 1
Fungsi 2

Tips

  • Gunakan closure untuk menyimpan state
  • Perhatikan memory leak
  • Hati-hati dengan variable capture
  • Dokumentasikan behavior closure
  • Closure berguna untuk callback dan event handler