0Pricing
Scala for Backend Engineering & Functional Programming · Pelajaran

Closure

Tangkap state.

Closure adalah pelajaran Scala for Backend Engineering & Functional Programming gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Scala for Backend Engineering & Functional Programming, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.

Apa itu penutupan?

Penutupan adalah fungsi yang menangkap variabel dari lingkup di sekitarnya, tempat fungsi tersebut didefinisikan. Fungsi ini "menutup" variabel-variabel tersebut, sehingga tetap dapat mengaksesnya bahkan setelah lingkup itu selesai.

object Main {
  def main(args: Array[String]): Unit = {
    val factor = 3
    val multiply = (x: Int) => x * factor
    println(multiply(5))
  }
}

Menangkap variabel bebas

Dalam x => x * factor, x adalah parameter, sedangkan factor adalah variabel bebas yang diambil dari lingkup luar. Fungsi tersebut menyimpan referensi ke variabel itu.

object Main {
  def main(args: Array[String]): Unit = {
    val greeting = "Hello"
    val greet = (name: String) => s"$greeting, $name!"
    println(greet("Ann"))
    println(greet("Bob"))
  }
}

Penutupan bertahan melampaui lingkupnya

Ketika sebuah fungsi mengembalikan penutupan, variabel yang ditangkap tetap hidup selama penutupan tersebut masih hidup, meskipun fungsi yang mendefinisikannya sudah selesai.

object Main {
  def makeAdder(n: Int): Int => Int = x => x + n
  def main(args: Array[String]): Unit = {
    val add10 = makeAdder(10)
    val add100 = makeAdder(100)
    println(add10(5))
    println(add100(5))
  }
}

Setiap penutupan memiliki tangkapan sendiri

Memanggil pabrik fungsi dua kali menghasilkan dua penutupan yang independen, masing-masing mengingat nilai yang ditangkapnya sendiri.

object Main {
  def prefixer(p: String): String => String = s => p + s
  def main(args: Array[String]): Unit = {
    val withDr = prefixer("Dr. ")
    val withMr = prefixer("Mr. ")
    println(withDr("Smith"))
    println(withMr("Jones"))
  }
}

Menangkap keadaan yang dapat diubah

Penutupan dapat menangkap sebuah var, lalu membaca dan memperbaruinya. Dengan demikian, penutupan dapat mempertahankan keadaan di antara pemanggilan, seperti penghitung.

object Main {
  def main(args: Array[String]): Unit = {
    var count = 0
    val increment = () => { count += 1; count }
    println(increment())
    println(increment())
    println(increment())
  }
}

Pabrik penghitung

Gabungkan gagasan-gagasan ini: fungsi yang mengembalikan penutupan yang menangkap var pribadinya sendiri memberi Anda penghitung yang terenkapsulasi dan independen.

object Main {
  def counter(): () => Int = {
    var n = 0
    () => { n += 1; n }
  }
  def main(args: Array[String]): Unit = {
    val c1 = counter()
    val c2 = counter()
    println(c1())
    println(c1())
    println(c2())
  }
}

Penutupan menangkap referensi, bukan salinan

Penutupan menangkap variabel, bukan cuplikan nilainya. Jika var yang ditangkap berubah setelah penutupan dibuat, penutupan tersebut akan melihat nilai yang baru.

object Main {
  def main(args: Array[String]): Unit = {
    var msg = "first"
    val show = () => println(msg)
    show()
    msg = "second"
    show()
  }
}

Utamakan menangkap val

Menangkap val yang tidak dapat diubah mencegah kejutan: nilai yang ditangkap tidak pernah berubah, sehingga penutupan berperilaku secara dapat diprediksi. Dalam kode fungsional, utamakan penangkapan val.

object Main {
  def main(args: Array[String]): Unit = {
    val taxRate = 0.2
    val withTax = (price: Double) => price * (1 + taxRate)
    println(withTax(100))
  }
}

Penutupan dengan metode koleksi

Lambdas yang diteruskan ke map, filter, dan sebagainya merupakan penutupan setiap kali merujuk ke variabel di luar. Ini sangat umum dalam Scala sehari-hari.

object Main {
  def main(args: Array[String]): Unit = {
    val threshold = 3
    val nums = List(1, 2, 3, 4, 5)
    val big = nums.filter(_ > threshold)
    println(big)
  }
}

Kesalahan penangkapan dalam perulangan

Dalam Scala, variabel perulangan for merupakan pengikatan baru pada setiap iterasi, sehingga penutupan menangkap nilai yang berbeda-beda. Hal ini mencegah kesalahan klasik yang terlihat dalam beberapa bahasa lain.

object Main {
  def main(args: Array[String]): Unit = {
    val fns = for (i <- 1 to 3) yield () => i
    println(fns.map(f => f()))
  }
}

Penutupan merangkum perilaku + data

Penutupan menggabungkan perilaku (tubuh fungsi) dengan data (variabel yang ditangkap). Ini merupakan alternatif ringan untuk objek kecil dengan satu metode.

object Main {
  def discounter(rate: Double): Double => Double = price => price * (1 - rate)
  def main(args: Array[String]): Unit = {
    val sale = discounter(0.25)
    println(sale(80))
    println(sale(200))
  }
}

Pemeriksaan singkat

Apa yang ditangkap oleh penutupan dari lingkup di sekitarnya?

Rangkuman

Anda telah mempelajari penutupan:

  • Penutupan menangkap variabel bebas dari lingkup luarnya
  • Variabel yang ditangkap bertahan melampaui fungsi yang mendefinisikannya
  • Setiap instans penutupan memiliki keadaan tangkapannya sendiri
  • Penutupan menangkap referensi, sehingga tangkapan yang dapat diubah dapat berubah
  • Lambda untuk map/filter merupakan penutupan sehari-hari

Pertanyaan yang Sering Diajukan

Apakah pelajaran “Closure” gratis?

Ya — teks lengkap “Closure” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Scala for Backend Engineering & Functional Programming, upgrade ke CoddyKit PRO. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.

Apa yang akan aku pelajari di “Closure”?

Tangkap state. Kamu berlatih Scala for Backend Engineering & Functional Programming dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.

Apakah aku perlu pengalaman untuk memulai Scala for Backend Engineering & Functional Programming?

Tidak diperlukan pengalaman sebelumnya. Scala for Backend Engineering & Functional Programming di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.

Berapa lama pelajaran “Closure” memakan waktu?

Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.

Bisakah aku menulis dan menjalankan kode dalam pelajaran Scala for Backend Engineering & Functional Programming ini?

Ya. Setiap pelajaran Scala for Backend Engineering & Functional Programming menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.

Semua pelajaran dalam kursus ini

  1. Fungsi sebagai Nilai
  2. Currying
  3. Komposisi
  4. Closure
← Kembali ke Scala for Backend Engineering & Functional Programming