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

คลาสชนิดข้อมูลและอิมพลิซิต

เรียนรู้การใช้คลาสชนิดข้อมูลสำหรับพหุสัณฐานแบบเฉพาะกิจ และใช้ประโยชน์จากระบบอิมพลิซิตของ Scala เพื่อสร้างนามธรรมที่ทรงพลัง

คลาสชนิดข้อมูลและอิมพลิซิต เป็นบทเรียน 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 บทเรียน

อธิบายพหุสัณฐานแบบเฉพาะกิจ

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

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

คลาสชนิดข้อมูลคืออะไร

คลาสประเภท คือรูปแบบการออกแบบที่ช่วยเพิ่มพฤติกรรมใหม่ให้กับประเภทข้อมูลที่มีอยู่แล้วได้โดยไม่ต้องแก้ไขประเภทข้อมูลเหล่านั้น และไม่ต้องใช้การสืบทอด

  • กำหนดสัญญา (เทรต) สำหรับพฤติกรรมเฉพาะอย่าง
  • จัดเตรียม 'อินสแตนซ์' (ออบเจ็กต์) ที่ใช้งานตามสัญญานี้สำหรับประเภทข้อมูลต่าง ๆ
  • ใช้กลไก โดยนัย ของ Scala เพื่อนำพฤติกรรมที่เหมาะสมเข้ามาในขอบเขตโดยอัตโนมัติ

การกำหนดเทรตของคลาสประเภท

ขั้นแรก เราจะกำหนดเทรตที่อธิบายพฤติกรรมที่ต้องการ เทรตนี้รับพารามิเตอร์ประเภทข้อมูล A ซึ่งแทนประเภทข้อมูลที่พฤติกรรมของเราจะทำงานด้วย

มาสร้างคลาสประเภท Printable ที่รู้วิธีแปลงประเภทข้อมูลใด ๆ ให้เป็นสตริงที่มนุษย์อ่านเข้าใจได้กัน

package com.coddykit

trait Printable[A] {
  def format(value: A): String
}

การสร้างอินสแตนซ์ของคลาสประเภท

ต่อไป เราต้องบอก Scala ว่า จะทำอย่างไร ให้ประเภทข้อมูลเฉพาะเป็น Printable เราทำเช่นนี้โดยสร้าง ออบเจ็กต์โดยนัย (หรือค่า) ที่ขยายเทรต Printable สำหรับแต่ละประเภทข้อมูล

สิ่งเหล่านี้เรียกว่า อินสแตนซ์ของคลาสประเภท

package com.coddykit

trait Printable[A] {
  def format(value: A): String
}

object PrintableInstances {
  implicit object StringPrintable extends Printable[String] {
    def format(value: String): String = s"'${value}'"
  }

  implicit object IntPrintable extends Printable[Int] {
    def format(value: Int): String = s"${value}i"
  }
}

การใช้คลาสประเภทกับค่าที่กำหนดโดยนัย

เมื่อต้องการใช้คลาสประเภท เราจะกำหนดฟังก์ชันที่รับพารามิเตอร์โดยนัยซึ่งมีประเภทเป็นคลาสประเภท คอมไพเลอร์ของ Scala จะค้นหาอินสแตนซ์โดยนัยของ Printable[A] ที่พร้อมใช้งานโดยอัตโนมัติเมื่อมีการเรียกใช้ฟังก์ชันนี้

หากพบ คอมไพเลอร์จะส่งอินสแตนซ์นั้นเข้าไปในฟังก์ชันให้โดยอัตโนมัติ

package com.coddykit

trait Printable[A] {
  def format(value: A): String
}

object PrintableInstances {
  implicit object StringPrintable extends Printable[String] {
    def format(value: String): String = s"'${value}'"
  }

  implicit object IntPrintable extends Printable[Int] {
    def format(value: Int): String = s"${value}i"
  }
}

object PrintableSyntax {
  def print[A](value: A)(implicit p: Printable[A]): Unit = {
    println(p.format(value))
  }
}

object Main {
  import PrintableInstances._
  import PrintableSyntax._

  def main(args: Array[String]): Unit = {
    print("hello")
    print(123)
  }
}

ขอบเขตบริบท: รูปแบบไวยากรณ์ที่กระชับขึ้น

Scala มีรูปแบบย่อที่เรียกว่า ขอบเขตบริบทสำหรับพารามิเตอร์โดยนัย แทนที่จะเขียน (implicit p: Printable[A]) คุณสามารถเขียน [A: Printable] ได้

วิธีนี้ทำให้โค้ดอ่านง่ายขึ้น โดยเฉพาะเมื่อมีพารามิเตอร์โดยนัยหลายตัว

package com.coddykit

trait Printable[A] {
  def format(value: A): String
}

object PrintableInstances {
  implicit object StringPrintable extends Printable[String] {
    def format(value: String): String = s"'${value}'"
  }

  implicit object IntPrintable extends Printable[Int] {
    def format(value: Int): String = s"${value}i"
  }
}

object PrintableSyntax {
  // Using context bound: [A: Printable] is shorthand for (implicit p: Printable[A])
  def print[A: Printable](value: A): Unit = {
    // To access the implicit instance, use implicitly[Printable[A]]
    val p = implicitly[Printable[A]]
    println(p.format(value))
  }
}

object Main {
  import PrintableInstances._
  import PrintableSyntax._

  def main(args: Array[String]): Unit = {
    print("world")
    print(456)
  }
}

การขยายไปยังประเภทข้อมูลแบบกำหนดเอง

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

มาทำให้คลาสแบบกรณี Person ของเราเป็น Printable กัน

package com.coddykit

trait Printable[A] {
  def format(value: A): String
}

case class Person(name: String, age: Int)

object PrintableInstances {
  implicit object StringPrintable extends Printable[String] {
    def format(value: String): String = s"'${value}'"
  }

  implicit object IntPrintable extends Printable[Int] {
    def format(value: Int): String = s"${value}i"
  }

  // New instance for our custom Person type
  implicit object PersonPrintable extends Printable[Person] {
    def format(person: Person): String = 
      s"Person(name: ${person.name}, age: ${person.age})"
  }
}

object PrintableSyntax {
  def print[A: Printable](value: A): Unit = {
    val p = implicitly[Printable[A]]
    println(p.format(value))
  }
}

object Main {
  import PrintableInstances._
  import PrintableSyntax._

  def main(args: Array[String]): Unit = {
    val alice = Person("Alice", 30)
    print(alice)
  }
}

ค่าที่กำหนดโดยนัย: มากกว่าคลาสประเภท

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

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

แนวคิดสำคัญคือ คอมไพเลอร์จะค้นหาการกำหนดโดยนัยที่เหมาะสมภายในขอบเขต

ประโยชน์ของคลาสประเภท

คลาสประเภทมีข้อดีหลายประการ:

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

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

พิจารณาคลาสประเภท Printable และอินสแตนซ์ของคลาสนี้จากบทเรียน หากเรียกใช้ print(10.5) โดยสมมติว่าไม่มีอินสแตนซ์ DoublePrintable จะเกิดอะไรขึ้น

สรุปและขั้นตอนถัดไป

คุณเข้าใจคลาสประเภทและระบบค่าที่กำหนดโดยนัยอันทรงพลังของ Scala ได้อย่างดีแล้ว

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

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

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

บทเรียน “คลาสชนิดข้อมูลและอิมพลิซิต” ฟรีหรือไม่

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

คุณจะเรียนรู้อะไรในบทเรียน “คลาสชนิดข้อมูลและอิมพลิซิต”

เรียนรู้การใช้คลาสชนิดข้อมูลสำหรับพหุสัณฐานแบบเฉพาะกิจ และใช้ประโยชน์จากระบบอิมพลิซิตของ Scala เพื่อสร้างนามธรรมที่ทรงพลัง คุณปฏิบัติ 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