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 บทเรียน

คุณลักษณะชนิดแบบใหม่

Scala 3 เพิ่มชนิดยูเนียน (A | B) และชนิดอินเตอร์เซกชัน (A & B) ให้กับระบบชนิด ทั้งสองช่วยให้คุณอธิบายค่าได้แม่นยำยิ่งขึ้นโดยไม่ต้องใช้ลำดับชั้นการสืบทอด

object Main:
  def main(args: Array[String]): Unit =
    println("Union: A | B, Intersection: A & B")

พื้นฐานชนิดยูเนียน

ชนิดยูเนียน A | B แทนค่าที่เป็น A หรือ B อย่างใดอย่างหนึ่ง เป็น OR เชิงทฤษฎีเซตบนชนิด

object Main:
  def show(x: Int | String): String = x match
    case i: Int    => s"int $i"
    case s: String => s"str $s"

  def main(args: Array[String]): Unit =
    println(show(42))
    println(show("hi"))

ยูเนียนไม่ต้องมีชนิดแม่ร่วมกัน

ต่างจาก Either ใน Scala 2 ชนิดยูเนียนไม่จำเป็นต้องมีตัวห่อหุ้ม ชนิดสองชนิดใด ๆ สามารถนำมาทำยูเนียนได้โดยไม่ต้องมีคลาสแม่ร่วมกัน

object Main:
  def parse(input: Int | Boolean): String =
    input match
      case n: Int     => s"number $n"
      case b: Boolean => s"flag $b"

  def main(args: Array[String]): Unit =
    println(parse(7))
    println(parse(true))

ใช้ยูเนียนเพื่อจำลองข้อผิดพลาด

ชนิดยูเนียนเหมาะสำหรับผลลัพธ์ข้อผิดพลาดแบบเบา ๆ โดยไม่ต้องมีชนิดตัวห่อหุ้ม เมื่อใช้ร่วมกับ enum หรือซิงเกิลตัน โค้ดจะอ่านได้ชัดเจน

case object NotFound

object Main:
  def lookup(id: Int): String | NotFound.type =
    if id == 1 then "Alice" else NotFound

  def main(args: Array[String]): Unit =
    println(lookup(1))
    println(lookup(2))

พื้นฐานชนิดอินเตอร์เซกชัน

ชนิดอินเตอร์เซกชัน A & B แทนค่าที่เป็นทั้ง A และ B เป็น AND เชิงทฤษฎีเซต และมักใช้เพื่อรวมเทรตเข้าด้วยกัน

trait Named:
  def name: String
trait Aged:
  def age: Int

object Main:
  def describe(p: Named & Aged): String =
    s"${p.name} is ${p.age}"

  def main(args: Array[String]): Unit =
    val person = new Named with Aged:
      def name = "Bob"
      def age = 40
    println(describe(person))

อินเตอร์เซกชันมีสมบัติสลับที่

ลำดับไม่มีผลต่อชนิดอินเตอร์เซกชัน: A & B เป็นชนิดเดียวกับ B & A ซึ่งแตกต่างจากชนิดผสม A with B ใน Scala 2 ที่ลำดับมีผลต่อการเลือกสมาชิกบางกรณี

trait Readable:
  def read: String
trait Writable:
  def write(s: String): Unit

object Main:
  def use(r: Readable & Writable): Unit =
    r.write("x")
    println(r.read)

  def main(args: Array[String]): Unit =
    val rw = new Readable with Writable:
      def read = "data"
      def write(s: String) = println(s"wrote $s")
    use(rw)

การรวมเทรตหลายรายการ

คุณสามารถทำอินเตอร์เซกชันของชนิดมากกว่าสองชนิดได้ ผลลัพธ์จะต้องมีความสามารถทั้งหมดที่ระบุไว้

trait A: def a: Int
trait B: def b: Int
trait C: def c: Int

object Main:
  def sum(x: A & B & C): Int = x.a + x.b + x.c

  def main(args: Array[String]): Unit =
    val v = new A with B with C:
      def a = 1
      def b = 2
      def c = 3
    println(sum(v))

นามแฝงชนิดสำหรับยูเนียน

คุณสามารถตั้งชื่อชนิดยูเนียนที่ยาวได้ด้วยนามแฝง type เพื่อให้ลายเซ็นอ่านง่ายขึ้น

type Json = Int | String | Boolean

object Main:
  def render(j: Json): String = j match
    case i: Int     => i.toString
    case s: String  => s"\"$s\""
    case b: Boolean => b.toString

  def main(args: Array[String]): Unit =
    println(render("hi"))
    println(render(true))

การจับคู่ยูเนียนอย่างครบถ้วน

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

type Shape = "circle" | "square"

object Main:
  def sides(s: Shape): Int = s match
    case "circle" => 0
    case "square" => 4

  def main(args: Array[String]): Unit =
    println(sides("square"))

การขยายกว้างของยูเนียน

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

object Main:
  def pick(flag: Boolean): Int | String =
    if flag then 1 else "one"

  def main(args: Array[String]): Unit =
    val x: Int | String = pick(false)
    println(x)

ควรใช้แต่ละแบบเมื่อใด

เลือกเครื่องมือให้เหมาะสม

  • ยูเนียน: ค่าเป็นหนึ่งในหลายชนิด (OR)
  • อินเตอร์เซกชัน: ค่าตรงตามเทรตหลายรายการพร้อมกัน (AND)
  • ยูเนียนช่วยหลีกเลี่ยงชนิดตัวห่อหุ้ม ส่วนอินเตอร์เซกชันช่วยหลีกเลี่ยงการสืบทอดที่ลึกเกินไป
trait Logger: def log(s: String): Unit
trait Clock:  def now: Long

object Main:
  def run(env: Logger & Clock): Unit =
    env.log(s"time=${env.now}")

  def main(args: Array[String]): Unit =
    val env = new Logger with Clock:
      def log(s: String) = println(s)
      def now = 100L
    run(env)

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

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

สรุปทบทวน

คุณได้เรียนรู้ชนิดยูเนียนและอินเตอร์เซกชันของ Scala 3

  • A | B: ค่าเป็น A หรือ B โดยไม่ต้องมีตัวห่อหุ้มหรือคลาสแม่ร่วมกัน
  • A & B: ค่าเป็นทั้ง A และ B และมีสมบัติสลับที่
  • ใช้การจับคู่รูปแบบเพื่อจำกัดชนิดยูเนียน และรวมเทรตด้วยอินเตอร์เซกชัน
  • ใช้นามแฝง type เพื่อตั้งชื่อยูเนียนที่ยาว
object Main:
  def length(x: String | List[Int]): Int = x match
    case s: String    => s.length
    case l: List[Int] => l.length

  def main(args: Array[String]): Unit =
    println(length("hello"))
    println(length(List(1, 2, 3)))

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

บทเรียน “ชนิดข้อมูลยูเนียนและอินเตอร์เซกชัน” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “ชนิดข้อมูลยูเนียนและอินเตอร์เซกชัน” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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. อีนัมใน Scala 3
  3. ชนิดข้อมูลทึบแสง
  4. ชนิดข้อมูลยูเนียนและอินเตอร์เซกชัน
← กลับไปที่ Scala for Backend Engineering & Functional Programming