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

สตรีมไม่สิ้นสุด

จำลองข้อมูลที่ไม่มีที่สิ้นสุดอย่างปลอดภัย

บทเรียน 3 จาก 413 ขั้นตอน

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

อนันต์อย่างปลอดภัย

LazyList สามารถอธิบายลำดับอนันต์ได้ เพราะส่วนท้ายจะไม่ถูกคำนวณจนกว่าจะมีการร้องขอ คุณจะสร้างเป็นรูปธรรมเฉพาะส่วนต้นที่ถูกใช้เท่านั้น

ทำให้คุณจำลองจำนวนธรรมชาติ จำนวนเฉพาะ หรือค่าจากเซนเซอร์ได้โดยไม่ต้องกำหนดขอบเขตล่วงหน้า

จำนวนธรรมชาติทั้งหมด

LazyList.from(1) คือลำดับอนันต์ 1, 2, 3, ... คุณสามารถดึงส่วนต้นที่มีจำนวนจำกัดได้

การบังคับให้ประเมินทั้งหมดจะไม่มีวันเสร็จ ดังนั้นให้ตัดช่วงด้วย take หรือหยุดด้วย predicate เสมอ

object Demo extends App {
  val nats = LazyList.from(1)
  println(nats.take(5).toList)
}

from พร้อมขั้น

LazyList.from(start, step) จะนับโดยเพิ่มช่วงคงที่ ใช้สำหรับจำนวนคู่ จังหวะสัญญาณ หรือ ลำดับเลขคณิตใด ๆ

ลำดับนี้เป็นอนันต์ แต่การเรียกใช้ take แต่ละครั้งจะบังคับให้ประเมินเฉพาะสิ่งที่คุณร้องขอ

object Demo extends App {
  val evens = LazyList.from(0, 2)
  println(evens.take(5).toList)
}

กระแสที่อ้างอิงถึงตัวเอง

เทคนิคที่มีชื่อเสียงคือการกำหนด LazyList โดยอ้างอิงถึงตัวมันเอง ลำดับฟีโบนัชชีสามารถเขียนได้โดย zip กระแสเข้ากับส่วนท้ายของตัวมันเอง

สิ่งนี้ทำงานได้เพราะส่วนท้ายยังไม่ถูกประเมินจนกว่าแต่ละเซลล์จะถูกดึงออกมา

lazy val fibs: LazyList[Int] =
  0 #:: 1 #:: fibs.zip(fibs.tail).map { case (a, b) => a + b }
// fibs(0)=0, fibs(1)=1, fibs(2)=1 ...

การเรียกใช้ฟีโบนัชชี

มาบังคับให้ประเมินส่วนต้นของกระแสฟีโบนัชชีที่อ้างอิงถึงตัวเองกัน

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

object Demo extends App {
  lazy val fibs: LazyList[Int] =
    0 #:: 1 #:: fibs.zip(fibs.tail).map { case (a, b) => a + b }
  println(fibs.take(10).toList)
}

iterate สำหรับลำดับ

LazyList.iterate สร้างลำดับอนันต์ด้วยฟังก์ชันการเปลี่ยนค่า เลขยกกำลัง การเติบโตแบบเรขาคณิต และเครื่องจักรสถานะ ล้วนเหมาะกับรูปแบบนี้

ในที่นี้สมาชิกแต่ละตัวมีค่าเป็นสามเท่าของสมาชิกก่อนหน้าไปตลอด

object Demo extends App {
  val triples = LazyList.iterate(1)(_ * 3)
  println(triples.take(6).toList)
}

ตะแกรงจำนวนเฉพาะ

กระแสอนันต์เหมาะอย่างยิ่งกับตะแกรงของเอราทอสเทนีส เลือกจำนวนเฉพาะที่ส่วนหัว กรองพหุคูณของมันออกจากส่วนที่เหลือ แล้วเรียกซ้ำ

การกรองเป็นแบบขี้เกียจ ดังนั้นจำนวนเฉพาะจะถูกสร้างทีละตัวเมื่อคุณใช้กระแส

def sieve(s: LazyList[Int]): LazyList[Int] =
  s.head #:: sieve(s.tail.filter(_ % s.head != 0))

val primes = sieve(LazyList.from(2))

การเรียกใช้ตะแกรง

ตอนนี้ดึงจำนวนเฉพาะสิบตัวแรกจากตะแกรงอนันต์นั้น

จะบังคับให้ประเมินกระแสตัวเลขพื้นฐานเพียงมากพอที่จะได้จำนวนเฉพาะสิบตัว ซึ่งแสดงให้เห็นการคำนวณตามความต้องการ

object Demo extends App {
  def sieve(s: LazyList[Int]): LazyList[Int] =
    s.head #:: sieve(s.tail.filter(_ % s.head != 0))
  val primes = sieve(LazyList.from(2))
  println(primes.take(10).toList)
}

อย่าบังคับให้ประเมินทั้งหมด

เมธอดที่ต้องใช้ลำดับทั้งหมด เช่น length, toList บนกระแสที่ไม่มีขอบเขต หรือ foreach ที่ไม่มีจุดหยุด จะค้างเมื่อใช้กับ LazyList อนันต์

กำหนดขอบเขตด้วย take, takeWhile หรือ find ก่อนเสมอ

// DON'T: LazyList.from(1).toList    // hangs forever
val ok = LazyList.from(1).take(3).toList

กับดักการเก็บส่วนหัว

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

สำหรับการเดินผ่านข้อมูลเป็นเวลานาน ให้ใช้เมธอดโดยไม่ผูกส่วนหัวไว้ หรือใช้ Iterator

เหตุผลที่กระแสอนันต์สำคัญ

กระแสอนันต์ช่วยแยกการสร้างออกจากการใช้ ผู้สร้างจะอธิบายกฎที่ดำเนินต่อไปไม่สิ้นสุด ส่วนผู้ใช้จะตัดสินใจว่าจะสร้างข้อมูลจริงมากเพียงใด

นี่เป็นรูปแบบเชิงฟังก์ชันที่ทรงพลังสำหรับ pipeline การจำลอง และแหล่งข้อมูลแบบขี้เกียจ

ตรวจสอบความเข้าใจอย่างรวดเร็ว

ทดสอบความเข้าใจเกี่ยวกับ LazyLists อนันต์

สรุปทบทวน

LazyList แบบไม่มีที่สิ้นสุดทำงานได้เพราะส่วนท้ายจะถูกสร้างตามความต้องการ: from, iterate, fibs ที่อ้างอิงตัวเอง และตะแกรงจำนวนเฉพาะ ล้วนสร้างข้อมูลต่อไปได้เรื่อย ๆ แต่จะสร้างจริงเฉพาะส่วนที่คุณเรียกใช้

หลีกเลี่ยงการดำเนินการกับลำดับทั้งหมดและการเก็บส่วนหัวไว้ จากนี้เราจะเรียนรู้การดึงข้อมูลและการกรองแบบขี้เกียจอย่างเชี่ยวชาญ

เริ่มต้นได้ฟรี

เรียนรู้ Scala ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
143

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

บทเรียน “สตรีมไม่สิ้นสุด” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “สตรีมไม่สิ้นสุด” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 3 จากทั้งหมด 4 บทเรียน

บทเรียน “สตรีมไม่สิ้นสุด” ใช้เวลานานแค่ไหน

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

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

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

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

  1. อธิบายการประเมินแบบขี้เกียจ
  2. สร้าง LazyList
  3. สตรีมไม่สิ้นสุด
  4. การดึงและกรองแบบขี้เกียจ
← กลับไปที่ Scala for Backend Engineering & Functional Programming