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

ความไม่เปลี่ยนรูปและผลข้างเคียง

ทำความเข้าใจความสำคัญของความไม่เปลี่ยนรูปในการเขียนโปรแกรมเชิงฟังก์ชัน และวิธีจัดการผลข้างเคียงอย่างมีประสิทธิภาพ

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

ไม่เปลี่ยนแปลงโดยการออกแบบ

ยินดีต้อนรับสู่บทเรียนเรื่อง ความไม่เปลี่ยนแปลงและผลข้างเคียง ครับ/ค่ะ! แนวคิดเหล่านี้เป็นหลักสำคัญของการเขียนโปรแกรมเชิงฟังก์ชัน (FP) และช่วยให้เราเขียนโค้ดที่สะอาดและคาดเดาได้มากขึ้น

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

val เทียบกับ var ใน Scala

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

มาดูความแตกต่างกัน:

object Main {
  def main(args: Array[String]): Unit = {
    // Immutable value
    val greeting = "Hello"
    // greeting = "Hi" // This would cause a compile error!

    // Mutable variable
    var count = 0
    count = 1 // This is allowed

    println(greeting)
    println(count)
  }
}

เหตุใดความไม่เปลี่ยนแปลงจึงสำคัญ

ความไม่เปลี่ยนแปลงนำประโยชน์สำคัญหลายประการมาสู่โค้ด โดยเฉพาะในระบบที่ทำงานพร้อมกันและระบบที่ซับซ้อน:

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

คอลเลกชันที่ไม่เปลี่ยนแปลง

ไลบรารีมาตรฐานของ Scala สนับสนุนคอลเลกชันที่ไม่เปลี่ยนแปลงเป็นค่าเริ่มต้น เมื่อคุณ 'แก้ไข' คอลเลกชันที่ไม่เปลี่ยนแปลง จริง ๆ แล้วคุณจะได้รับคอลเลกชันใหม่ที่มีการเปลี่ยนแปลง โดยคอลเลกชันเดิมยังคงไม่ถูกแตะต้อง

ตัวอย่างคอลเลกชัน List ที่ไม่เปลี่ยนแปลงมีดังนี้:

object Main {
  def main(args: Array[String]): Unit = {
    val numbers = List(1, 2, 3)
    val newNumbers = numbers :+ 4 // Creates a new list

    println(s"Original list: $numbers")
    println(s"New list: $newNumbers")
  }
}

ทำความเข้าใจผลข้างเคียง

ผลข้างเคียงแตกต่างจากความไม่เปลี่ยนแปลง โดยเกิดขึ้นเมื่อฟังก์ชันหรือนิพจน์ทำสิ่งอื่นนอกเหนือจากการส่งคืนค่าเพียงอย่างเดียว เช่น โต้ตอบกับ 'โลกภายนอก' หรือเปลี่ยนแปลงสถานะที่เปลี่ยนแปลงได้

ผลข้างเคียงที่พบบ่อย ได้แก่:

  • การแก้ไขตัวแปรส่วนกลางหรือออบเจ็กต์ที่เปลี่ยนแปลงได้
  • การพิมพ์ลงคอนโซล (I/O)
  • การเขียนลงไฟล์หรือฐานข้อมูล
  • การเปลี่ยนแปลงนาฬิกาของระบบ

ปัญหาของผลข้างเคียง

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

  • ทำความเข้าใจได้ยากขึ้น: ผลลัพธ์ของฟังก์ชันอาจขึ้นอยู่กับสถานะภายนอก ทำให้คาดเดาได้ยาก
  • ทดสอบได้ยาก: การทดสอบต้องเตรียมและล้างสถานะภายนอก
  • ปัญหาการทำงานพร้อมกัน: เธรดหลายรายการที่ก่อผลข้างเคียงอาจทำให้เกิดสภาวะแข่งขันและจุดบกพร่อง

การระบุผลข้างเคียงในโค้ด

มาดูตัวอย่าง Scala กัน ฟังก์ชันหนึ่งมีผลข้างเคียง ส่วนอีกฟังก์ชันไม่มี คุณสังเกตเห็นความแตกต่างได้หรือไม่

object Main {
  var total = 0 // A mutable global variable

  // Function with a side effect
  def addAndPrint(x: Int, y: Int): Int = {
    total = x + y // Modifies global state
    println(s"Sum is: $total") // I/O side effect
    total
  }

  // Function without side effects (pure function)
  def pureAdd(x: Int, y: Int): Int = {
    x + y // Only returns a value
  }

  def main(args: Array[String]): Unit = {
    addAndPrint(5, 3)
    println(s"Global total: $total")
    println(s"Pure sum: ${pureAdd(5, 3)}")
  }
}

ฟังก์ชันบริสุทธิ์: อุดมคติของ FP

เป้าหมายสูงสุดของ FP คือการเขียนฟังก์ชันบริสุทธิ์ ฟังก์ชันบริสุทธิ์มีลักษณะสำคัญสองประการ:

  1. ให้ผลลัพธ์เดียวกันเสมอเมื่อได้รับอินพุตเดียวกัน (กำหนดผลลัพธ์ได้แน่นอน)
  2. ไม่ก่อให้เกิดผลข้างเคียง (ไม่เปลี่ยนแปลงสิ่งใดนอกขอบเขตของฟังก์ชัน)

ฟังก์ชัน pureAdd ในตัวอย่างก่อนหน้านี้เป็นฟังก์ชันบริสุทธิ์!

การจัดการผลข้างเคียง

เนื่องจากผลข้างเคียงบางอย่างหลีกเลี่ยงไม่ได้ (เช่น การพิมพ์ผลลัพธ์หรือการบันทึกข้อมูล) แนวทางของ FP คือ:

  • แยกผลข้างเคียงออก: แยกฟังก์ชันที่มีผลข้างเคียงออกจากฟังก์ชันบริสุทธิ์
  • ผลักไปไว้ที่ขอบของระบบ: ดำเนินการ I/O ในตอนเริ่มต้นหรือตอนสิ้นสุดโปรแกรม หรือภายในส่วนที่จัดไว้เฉพาะสำหรับการทำงานที่ก่อผล
  • ใช้โครงสร้างของ FP: ไลบรารีมักมีชนิดข้อมูล (เช่น IO หรือ Task) สำหรับแทนค่าและจัดการผลกระทบอย่างชัดเจน

ตรวจสอบความเข้าใจ

จากสิ่งที่คุณเรียนรู้มา ข้อความใดต่อไปนี้เกี่ยวกับความไม่เปลี่ยนแปลงและผลข้างเคียงในการเขียนโปรแกรมเชิงฟังก์ชันเป็นจริง

ทบทวน: ความไม่เปลี่ยนแปลงและผลกระทบ

ทำได้ดีมากครับ/ค่ะ! ในบทเรียนนี้ เราได้สำรวจแนวคิดสำคัญเรื่องความไม่เปลี่ยนแปลงและผลข้างเคียงในการเขียนโปรแกรมเชิงฟังก์ชัน

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

การเชี่ยวชาญแนวคิดเหล่านี้เป็นกุญแจสำคัญในการเขียนแอปพลิเคชัน Scala เชิงฟังก์ชันที่แข็งแกร่งและสวยงาม!

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

บทเรียน “ความไม่เปลี่ยนรูปและผลข้างเคียง” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “ความไม่เปลี่ยนรูปและผลข้างเคียง”

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

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

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

บทเรียน “ความไม่เปลี่ยนรูปและผลข้างเคียง” ใช้เวลานานแค่ไหน

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

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

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

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

  1. ฟังก์ชันในฐานะค่าอันดับหนึ่ง
  2. ฟังก์ชันลำดับสูงและการทำเคอร์รี
  3. ความไม่เปลี่ยนรูปและผลข้างเคียง
← กลับไปที่ Scala for Backend Engineering & Functional Programming