โคลเชอร์
จับสถานะไว้ใช้
โคลเชอร์ เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ