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

การกำหนดอินสแตนซ์

อินสแตนซ์โดยนัย

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

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

การกำหนดอินสแตนซ์

อินสแตนซ์ บอกคอมไพเลอร์ว่าคลาสประเภทมีพฤติกรรมอย่างไรสำหรับชนิดข้อมูลหนึ่ง ๆ ใน Scala อินสแตนซ์มักกำกับด้วย implicit (Scala 2) หรือประกาศด้วย given (Scala 3) เพื่อให้ค้นพบโดยอัตโนมัติ

อินสแตนซ์ implicit val

สำหรับคลาสประเภทแบบง่าย implicit val ก็เพียงพอแล้ว คอมไพเลอร์จะค้นพบเมื่อฟังก์ชันต้องการ Show[Int]

trait Show[A] { def show(a: A): String }

object Main {
  implicit val intShow: Show[Int] = (a: Int) => s"Int=$a"

  def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

  def main(args: Array[String]): Unit = {
    println(display(123))
  }
}

implicitly: เรียกใช้อินสแตนซ์

implicitly[Show[Int]] ขอให้คอมไพเลอร์ดึงอินสแตนซ์ที่อยู่ในขอบเขตมาให้ มีประโยชน์สำหรับทดสอบว่ามีอินสแตนซ์อยู่ หรือสำหรับเข้าถึงอินสแตนซ์โดยตรง

trait Show[A] { def show(a: A): String }

object Main {
  implicit val intShow: Show[Int] = (a: Int) => s"<$a>"

  def main(args: Array[String]): Unit = {
    val s = implicitly[Show[Int]]
    println(s.show(8))
  }
}

อินสแตนซ์สำหรับชนิดข้อมูลที่กำหนดเอง

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

trait Show[A] { def show(a: A): String }

case class Point(x: Int, y: Int)

object Main {
  implicit val pointShow: Show[Point] = (p: Point) => s"(${p.x}, ${p.y})"

  def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

  def main(args: Array[String]): Unit = {
    println(display(Point(3, 4)))
  }
}

implicit def สำหรับอินสแตนซ์ทั่วไป

เมื่ออินสแตนซ์ขึ้นอยู่กับอินสแตนซ์อื่น ให้ใช้ implicit def ในที่นี้ Show[List[A]] ถูกสร้างจาก Show[A]

trait Show[A] { def show(a: A): String }

object Main {
  implicit val intShow: Show[Int] = (a: Int) => a.toString

  implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
    (xs: List[A]) => xs.map(s.show).mkString("[", ", ", "]")

  def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

  def main(args: Array[String]): Unit = {
    println(display(List(1, 2, 3)))
  }
}

อินสแตนซ์ในออบเจกต์คู่กาย

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

trait Show[A] { def show(a: A): String }

object Show {
  implicit val intShow: Show[Int] = (a: Int) => s"i:$a"
  implicit val strShow: Show[String] = (a: String) => s"s:$a"
}

object Main {
  def display[A](a: A)(implicit s: Show[A]): String = s.show(a)

  def main(args: Array[String]): Unit = {
    println(display(5))
    println(display("hi"))
  }
}

ขอบเขตและลำดับความสำคัญของ implicit

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

รูปแบบย่อของขอบเขตบริบท

ไวยากรณ์ def f[A: Show](a: A) คือขอบเขตบริบท หมายความว่าต้องมี Show[A] แบบอิมพลิซิตอยู่ในขอบเขต ภายในฟังก์ชัน ให้เรียกใช้ด้วย implicitly

trait Show[A] { def show(a: A): String }

object Main {
  implicit val intShow: Show[Int] = (a: Int) => s"n=$a"

  def display[A: Show](a: A): String = implicitly[Show[A]].show(a)

  def main(args: Array[String]): Unit = {
    println(display(77))
  }
}

ตัวช่วยเรียกใช้อินสแตนซ์

ไลบรารีจะเพิ่มเมธอด apply ให้กับออบเจกต์คู่กายเพื่อใช้เป็นตัวเรียกใช้อินสแตนซ์ที่สะดวก โดย Show[Int] จะคืนค่าอินสแตนซ์ วิธีนี้อ่านง่ายกว่า implicitly

trait Show[A] { def show(a: A): String }

object Show {
  def apply[A](implicit s: Show[A]): Show[A] = s
  implicit val intShow: Show[Int] = (a: Int) => s"=$a"
}

object Main {
  def main(args: Array[String]): Unit = {
    println(Show[Int].show(10))
  }
}

หลีกเลี่ยงอินสแตนซ์กำพร้า

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

นำทุกอย่างมาประกอบกัน

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

trait Show[A] { def show(a: A): String }

object Show {
  def apply[A](implicit s: Show[A]): Show[A] = s
  implicit val intShow: Show[Int] = _.toString
  implicit def listShow[A](implicit s: Show[A]): Show[List[A]] =
    (xs: List[A]) => xs.map(s.show).mkString(", ")
}

object Main {
  def main(args: Array[String]): Unit = {
    println(Show[List[Int]].show(List(4, 5, 6)))
  }
}

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

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

สรุปทบทวน

คุณได้เรียนรู้การกำหนดอินสแตนซ์:

  • implicit val สำหรับอินสแตนซ์แบบง่าย และ implicit def สำหรับอินสแตนซ์ที่สร้างต่อยอด
  • เรียกใช้อินสแตนซ์ด้วย implicitly หรือ apply ในออบเจกต์คู่กาย
  • ใช้ขอบเขตบริบท [A: Show] เป็นรูปแบบย่อ
  • วางอินสแตนซ์ในออบเจกต์คู่กายเพื่อหลีกเลี่ยงอินสแตนซ์กำพร้า
เริ่มต้นได้ฟรี

เรียนรู้ 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 ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 2 จากทั้งหมด 4 บทเรียน

บทเรียน “การกำหนดอินสแตนซ์” ใช้เวลานานแค่ไหน

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

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

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

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

  1. รูปแบบคลาสของชนิด
  2. การกำหนดอินสแตนซ์
  3. คลาสของชนิดที่พบบ่อย
  4. การอนุมานคลาสของชนิด
← กลับไปที่ Scala for Backend Engineering & Functional Programming