การใช้ร่วมกับ Option และ Future
การเชื่อมต่อแบบโมนาดิก
การใช้ร่วมกับ Option และ Future เป็นบทเรียน 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 บทเรียน
นอกเหนือจากคอลเลกชัน
for-comprehension ไม่ได้จำกัดอยู่แค่ลิสต์ ประเภทใดก็ตามที่มี map และ flatMap ก็สามารถใช้ได้ รวมถึง Option, Either, Try และ Future แนวทางนี้เรียกว่า การเชื่อมโยงแบบโมนาดิก
object Main {
def main(args: Array[String]): Unit = {
val sum = for {
a <- Some(10)
b <- Some(20)
} yield a + b
println(sum)
}
}Option หยุดการทำงานทันทีเมื่อพบ None
เมื่อใช้ Option การทำความเข้าใจจะสร้างผลลัพธ์ก็ต่อเมื่อตัวสร้าง ทุกตัว เป็น Some หากมีตัวใดเป็น None ผลลัพธ์ทั้งหมดจะเป็น None และขั้นตอนถัดไปจะถูกข้าม
object Main {
def main(args: Array[String]): Unit = {
val ok = for {
a <- Some(2)
b <- Some(3)
} yield a * b
val missing = for {
a <- Some(2)
b <- None: Option[Int]
} yield a * b
println(ok)
println(missing)
}
}การเชื่อมโยงการค้นหาค่าที่อาจไม่มี
รูปแบบที่ใช้บ่อยคือการค้นหาคีย์ใน Map ซึ่งการค้นหาแต่ละครั้งจะคืนค่าเป็น Option for-comprehension จะให้ค่าก็ต่อเมื่อการค้นหาทั้งหมดสำเร็จ
object Main {
def main(args: Array[String]): Unit = {
val prices = Map("apple" -> 3, "bread" -> 5)
val total = for {
a <- prices.get("apple")
b <- prices.get("bread")
} yield a + b
println(total)
val missing = for {
a <- prices.get("apple")
c <- prices.get("milk")
} yield a + c
println(missing)
}
}เหตุใดจึงดีกว่า if-else ซ้อนกัน
หากไม่ใช้ for-comprehension คุณจะต้องซ้อนการจับคู่รูปแบบหรือการตรวจสอบค่า null รูปแบบโมนาดิกจะคลี่พีระมิดนั้นออกเป็นลำดับเชิงเส้นที่อ่านง่าย
object Main {
def parse(s: String): Option[Int] = s.toIntOption
def main(args: Array[String]): Unit = {
val result = for {
x <- parse("40")
y <- parse("2")
} yield x + y
println(result)
}
}การ์ดใช้กับ Option ได้เช่นกัน
การ์ดภายในการทำความเข้าใจแบบ Option จะเปลี่ยนค่าเป็น None เมื่อเงื่อนไขไม่ผ่าน ทำหน้าที่เป็นการตรวจสอบแบบแทรกในโค้ด
object Main {
def main(args: Array[String]): Unit = {
def validate(age: Int): Option[Int] =
for {
a <- Some(age)
if a >= 18
} yield a
println(validate(25))
println(validate(15))
}
}แนะนำ Future
Future แทนค่าที่จะพร้อมใช้งานในภายหลัง เช่นเดียวกับ Option ที่มี map และ flatMap ดังนั้น for-comprehension จึงสามารถเรียงลำดับขั้นตอนแบบไม่พร้อมกันได้
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val f = for {
a <- Future(10)
b <- Future(20)
} yield a + b
println(Await.result(f, 2.seconds))
}
}Future ทำงานตามลำดับในกรณีนี้
เมื่อเครื่องกำเนิดหนึ่งขึ้นอยู่กับอีกเครื่องกำเนิดหนึ่งภายใน for-comprehension ฟิวเจอร์จะทำงานตามลำดับ เพราะการเรียก flatMap แต่ละครั้งจะรอผลลัพธ์ก่อนหน้า
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val f = for {
a <- Future(5)
b <- Future(a * 2)
} yield a + b
println(Await.result(f, 2.seconds))
}
}การเรียกใช้ Future แบบขนาน
หากต้องการให้ฟิวเจอร์ทำงานแบบขนาน ให้เริ่มฟิวเจอร์เหล่านั้น ก่อน for-comprehension แล้วจึงนำมารวมกัน งานที่เป็นอิสระต่อกันจะทำงานทับซ้อนกันแทนการรอคอย
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Await
import scala.concurrent.duration._
object Main {
def main(args: Array[String]): Unit = {
val fa = Future(100)
val fb = Future(200)
val combined = for {
a <- fa
b <- fb
} yield a + b
println(Await.result(combined, 2.seconds))
}
}Either สำหรับข้อผิดพลาดที่มีรายละเอียดมากขึ้น
Either[E, A] จะเก็บค่าข้อผิดพลาดไว้เมื่อการทำงานล้มเหลว ใน for-comprehension เมื่อพบ Left ตัวแรก การทำงานจะหยุดทันทีและคืนค่า Left นั้น
object Main {
def parse(s: String): Either[String, Int] =
s.toIntOption.toRight(s"not a number: $s")
def main(args: Array[String]): Unit = {
val good = for { a <- parse("3"); b <- parse("4") } yield a + b
val bad = for { a <- parse("3"); b <- parse("x") } yield a + b
println(good)
println(bad)
}
}รูปแบบเดียวกันกับหลายประเภท
สังเกตว่าโครงสร้างของการทำความเข้าใจนั้น เหมือนกันทุกประการ ไม่ว่าจะใช้ Option, Either, Try หรือ Future สิ่งที่แตกต่างมีเพียงความหมายของความล้มเหลว ความสม่ำเสมอนี้คือพลังของการเชื่อมโยงแบบโมนาดิก
import scala.util.Try
object Main {
def main(args: Array[String]): Unit = {
val result = for {
a <- Try("21".toInt)
b <- Try("2".toInt)
} yield a * b
println(result)
}
}ไม่อนุญาตให้ผสมประเภท
ตัวสร้างทั้งหมดในการทำความเข้าใจเดียวกันต้องเป็นโมนาดชนิดเดียวกัน คุณไม่สามารถผสมตัวสร้าง Option กับตัวสร้าง Future ได้โดยตรง ต้องแปลงประเภทใดประเภทหนึ่งก่อน เช่น ใช้ Future.fromTry หรือห่อหุ้ม Option
object Main {
def main(args: Array[String]): Unit = {
// Convert the Option to keep types consistent
val maybe: Option[Int] = Some(7)
val result = for {
a <- maybe
b <- maybe.map(_ + 1)
} yield a + b
println(result)
}
}ตรวจสอบอย่างรวดเร็ว
ในการทำความเข้าใจแบบ Option จะเกิดอะไรขึ้นหากตัวสร้างตัวหนึ่งให้ค่าเป็น None
สรุปทบทวน
คุณได้เรียนรู้การเชื่อมโยงแบบโมนาดิกด้วย for-comprehension:
- ใช้ได้กับทุกประเภทที่มี
mapและflatMap Optionจะหยุดการทำงานทันทีเมื่อพบNoneEitherและTryจะหยุดการทำงานเมื่อเกิดความล้มเหลว พร้อมเก็บข้อมูลข้อผิดพลาดไว้Futureจะเรียงลำดับขั้นตอนแบบไม่พร้อมกัน ควรเริ่มขั้นตอนเหล่านั้นตั้งแต่เนิ่น ๆ หากต้องการทำงานแบบขนาน- ตัวสร้างทั้งหมดต้องใช้ประเภทโมนาดเดียวกัน
คำถามที่พบบ่อย
บทเรียน “การใช้ร่วมกับ Option และ Future” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “การใช้ร่วมกับ Option และ Future” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส Scala for Backend Engineering & Functional Programming ให้อัปเกรดเป็น CoddyKit PRO คอร์ส Scala for Backend Engineering & Functional Programming มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “การใช้ร่วมกับ Option และ Future”
การเชื่อมต่อแบบโมนาดิก คุณปฏิบัติ Scala for Backend Engineering & Functional Programming ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน Scala for Backend Engineering & Functional Programming หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน Scala for Backend Engineering & Functional Programming บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “การใช้ร่วมกับ Option และ Future” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน Scala for Backend Engineering & Functional Programming นี้ได้ไหม
ได้ บทเรียน Scala for Backend Engineering & Functional Programming ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- การคลี่รูป for
- การกรองด้วย if
- ตัวสร้างหลายตัว
- การใช้ร่วมกับ Option และ Future