0Pricing
Scala for Backend Engineering & Functional Programming · บทเรียน

โคลเชอร์

จับสถานะไว้ใช้

โคลเชอร์ เป็นบทเรียน Scala for Backend Engineering & Functional Programming ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน Scala for Backend Engineering & Functional Programming และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

โคลเชอร์คืออะไร

โคลเชอร์ คือฟังก์ชันที่เก็บตัวแปรจากขอบเขตโดยรอบซึ่งเป็นจุดที่ฟังก์ชันนั้นถูกกำหนดไว้ โคลเชอร์จะ “ปิดล้อม” ตัวแปรเหล่านั้น ทำให้ยังเข้าถึงตัวแปรได้แม้ขอบเขตนั้นจะสิ้นสุดการทำงานแล้ว

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

การเก็บตัวแปรอิสระ

ใน x => x * factor x เป็นพารามิเตอร์ แต่ factor เป็นตัวแปรอิสระที่นำมาจากขอบเขตภายนอก ฟังก์ชันจะเก็บการอ้างอิงไปยังตัวแปรนั้นไว้

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

โคลเชอร์มีอายุยืนกว่าขอบเขต

เมื่อฟังก์ชันคืนค่าโคลเชอร์ ตัวแปรที่ถูกเก็บไว้จะยังคงอยู่ตราบเท่าที่โคลเชอร์ยังอยู่ แม้ว่าฟังก์ชันที่กำหนดโคลเชอร์นั้นจะทำงานเสร็จแล้วก็ตาม

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))
  }
}

โคลเชอร์แต่ละตัวมีค่าที่เก็บไว้เป็นของตนเอง

การเรียกโรงงานสร้างฟังก์ชันสองครั้งจะสร้างโคลเชอร์ที่เป็นอิสระต่อกันสองตัว โดยแต่ละตัวจะจดจำค่าที่ตนเองเก็บไว้

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"))
  }
}

การเก็บสถานะที่เปลี่ยนแปลงได้

โคลเชอร์สามารถเก็บ var และอ่านรวมถึงอัปเดตค่าได้ ทำให้โคลเชอร์รักษาสถานะระหว่างการเรียกแต่ละครั้งได้ เช่น ตัวนับ

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

โรงงานสร้างตัวนับ

ลองรวมแนวคิดต่าง ๆ เข้าด้วยกัน: ฟังก์ชันที่คืนค่าโคลเชอร์ซึ่งเก็บ var ส่วนตัวของตนเอง จะทำให้คุณมีตัวนับที่ห่อหุ้มและเป็นอิสระจากกัน

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())
  }
}

โคลเชอร์เก็บการอ้างอิง ไม่ใช่สำเนา

โคลเชอร์จะเก็บตัวแปร ไม่ใช่ภาพค่าที่บันทึกไว้ หาก var ที่ถูกเก็บไว้เปลี่ยนแปลงหลังจากสร้างโคลเชอร์แล้ว โคลเชอร์ก็จะเห็นค่าใหม่

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

เลือกเก็บ val เป็นหลัก

การเก็บ val ที่เปลี่ยนแปลงไม่ได้จะช่วยหลีกเลี่ยงความประหลาดใจ เนื่องจากค่าที่เก็บไว้จะไม่เปลี่ยนแปลง โคลเชอร์จึงทำงานได้อย่างคาดเดาได้ ในโค้ดเชิงฟังก์ชัน ควรเลือกเก็บ val เป็นหลัก

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

โคลเชอร์กับเมธอดของคอลเลกชัน

แลมบ์ดาที่ส่งให้ map, filter และอื่น ๆ จะเป็นโคลเชอร์เมื่ออ้างอิงตัวแปรภายนอก ซึ่งพบได้บ่อยมากในการเขียน Scala ในชีวิตประจำวัน

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)
  }
}

ข้อควรระวังในการเก็บค่าในลูป

ใน Scala ตัวแปรของลูป for จะเป็นการผูกค่าใหม่ในแต่ละรอบ ดังนั้นโคลเชอร์จึงเก็บค่าที่แยกจากกัน วิธีนี้ช่วยหลีกเลี่ยงข้อผิดพลาดคลาสสิกที่พบในภาษาอื่นบางภาษา

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

โคลเชอร์ห่อหุ้มการทำงานและข้อมูล

โคลเชอร์รวมการทำงาน (เนื้อหาฟังก์ชัน) เข้ากับข้อมูล (ตัวแปรที่เก็บไว้) จึงเป็นทางเลือกที่มีน้ำหนักเบาแทนออบเจ็กต์ขนาดเล็กที่มีเมธอดเดียว

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))
  }
}

ตรวจสอบอย่างรวดเร็ว

โคลเชอร์เก็บอะไรจากขอบเขตโดยรอบ

สรุปทบทวน

คุณได้เรียนรู้เกี่ยวกับโคลเชอร์ดังนี้:

  • โคลเชอร์เก็บตัวแปรอิสระจากขอบเขตภายนอก
  • ตัวแปรที่ถูกเก็บไว้มีอายุยืนกว่าฟังก์ชันที่กำหนดตัวแปรนั้น
  • โคลเชอร์แต่ละอินสแตนซ์มีสถานะที่เก็บไว้เป็นของตนเอง
  • โคลเชอร์เก็บการอ้างอิง ดังนั้นค่าที่เก็บแบบเปลี่ยนแปลงได้จึงเปลี่ยนได้
  • แลมบ์ดาที่ส่งให้ map/filter เป็นโคลเชอร์ที่พบได้ทั่วไป

คำถามที่พบบ่อย

บทเรียน “โคลเชอร์” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โคลเชอร์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โคลเชอร์”

จับสถานะไว้ใช้ คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน

บทเรียน “โคลเชอร์” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม

ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. ฟังก์ชันในฐานะค่า
  2. การทำเคอร์รี
  3. การประกอบฟังก์ชัน
  4. โคลเชอร์
← กลับไปที่ Scala for Backend Engineering & Functional Programming