ชนิดข้อมูลทึบแสง
การนามธรรมที่ไม่มีต้นทุน
ชนิดข้อมูลทึบแสง เป็นบทเรียน 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 บทเรียน
ชนิดแบบทึบคืออะไร
ชนิดแบบทึบเป็นความสามารถของ Scala 3 สำหรับสร้าง นามธรรมที่ไม่มีต้นทุน ชนิดนี้จะเป็นชนิดที่แตกต่างกันขณะคอมไพล์ แต่เมื่อคอมไพล์แล้วจะใช้ชนิดพื้นฐานโดยไม่มีการห่อค่าขณะรันไทม์
- ความปลอดภัยของชนิดเช่นเดียวกับคลาสห่อค่า
- ไม่มีต้นทุนการจองหน่วยความจำ
object Distances:
opaque type Meters = Double
object Main:
def main(args: Array[String]): Unit =
println("Opaque types compile to their underlying type")การประกาศชนิดแบบทึบ
ประกาศชนิดแบบทึบภายในออบเจกต์หรือคลาส นอกขอบเขตนั้น Meters และ Double จะถือเป็นคนละชนิดกัน
object Distances:
opaque type Meters = Double
def meters(d: Double): Meters = d
def toDouble(m: Meters): Double = m
object Main:
def main(args: Array[String]): Unit =
val d = Distances.meters(5.0)
println(Distances.toDouble(d))ขอบเขตของความทึบ
ภายในขอบเขตที่กำหนด ชนิดแบบทึบกับชนิดพื้นฐานสามารถใช้แทนกันได้ ภายนอก จะมองเห็นเฉพาะชนิดแบบทึบ จึงไม่สามารถส่ง Double ดิบในตำแหน่งที่ต้องการ Meters โดยไม่ตั้งใจได้
object Distances:
opaque type Meters = Double
def apply(d: Double): Meters = d
def show(m: Meters): String = s"$m m"
object Main:
def main(args: Array[String]): Unit =
val m = Distances(10.0)
println(Distances.show(m))การเพิ่มเมธอดส่วนขยาย
เพิ่มพฤติกรรมให้ชนิดแบบทึบด้วย เมธอดส่วนขยายที่กำหนดในขอบเขตเดียวกัน ผู้เรียกใช้จะได้การดำเนินการที่สะดวก โดยไม่ต้องเปิดเผยชนิดพื้นฐาน
object Distances:
opaque type Meters = Double
def apply(d: Double): Meters = d
extension (m: Meters)
def +(other: Meters): Meters = m + other
def value: Double = m
object Main:
def main(args: Array[String]): Unit =
val total = Distances(3.0) + Distances(4.0)
println(total.value)การป้องกันการสับสนระหว่างชนิด
ข้อดีสำคัญคือ ชนิดแบบทึบสองชนิดที่ใช้ชนิดพื้นฐานเดียวกันจะ ใช้แทนกันไม่ได้ Meters จึงไม่อาจถูกสับสนกับ Kilometers แม้ว่าทั้งคู่จะเป็น Double ก็ตาม
object Units:
opaque type Meters = Double
opaque type Kilometers = Double
def m(d: Double): Meters = d
def km(d: Double): Kilometers = d
def toMeters(k: Kilometers): Meters = k * 1000
object Main:
def main(args: Array[String]): Unit =
val far = Units.km(2.0)
println(Units.toMeters(far))ชนิดแบบทึบพร้อมขอบเขต
คุณสามารถกำหนด ขอบเขตบนให้ชนิดแบบทึบด้วย <: วิธีนี้จะเปิดเผย API สาธารณะบางส่วน แต่ยังซ่อนรูปแบบการแทนค่าที่แน่นอนไว้
object Ids:
opaque type UserId <: Int = Int
def apply(i: Int): UserId = i
object Main:
def main(args: Array[String]): Unit =
val id = Ids(99)
println(id + 1)การสร้างค่าอัจฉริยะพร้อมการตรวจสอบ
ผสานชนิดทึบแสงเข้ากับโรงงานที่ตรวจสอบค่า เพื่อให้มั่นใจว่าค่าจะถูกต้องตามข้อกำหนดเสมอ ตัวสร้างจะยังคงเป็นส่วนตัว และมีเพียงโรงงานที่ตรวจสอบแล้วเท่านั้นที่เป็นสาธารณะ
object Ages:
opaque type Age = Int
def of(i: Int): Option[Age] =
if i >= 0 && i < 150 then Some(i) else None
extension (a: Age) def value: Int = a
object Main:
def main(args: Array[String]): Unit =
println(Ages.of(30).map(_.value))
println(Ages.of(-1))ต้นทุนขณะทำงานเป็นศูนย์
แตกต่างจากตัวห่อหุ้มแบบคลาสค่าหรือคลาสกรณี ชนิดทึบแสงจะสร้างไม่มีออบเจ็กต์ขณะทำงาน List ของ Meters คือรายการของ double โดยตรงใน JVM จึงไม่มีการห่อค่า
object Temps:
opaque type Celsius = Double
def c(d: Double): Celsius = d
extension (t: Celsius) def value: Double = t
object Main:
def main(args: Array[String]): Unit =
val readings = List(Temps.c(20.0), Temps.c(21.5))
println(readings.map(_.value).sum)ชนิดทึบแสงเทียบกับนามแฝงชนิด
นามแฝง type X = Y แบบธรรมดามีความโปร่งใส กล่าวคือ X และ Y ใช้แทนกันได้ทุกที่ ชนิดที่ทึบแสงจะซ่อนความเท่าเทียมกันนี้นอกขอบเขต จึงให้ความปลอดภัยด้านชนิดอย่างแท้จริง
object Demo:
type Name = String // transparent alias
opaque type Email = String // opaque
def email(s: String): Email = s
extension (e: Email) def raw: String = e
object Main:
def main(args: Array[String]): Unit =
val e = Demo.email("a@b.com")
println(e.raw)ชนิดทึบแสงเทียบกับตัวห่อหุ้มแบบคลาสกรณี
ตัวห่อหุ้มแบบคลาสกรณี เช่น case class Meters(value: Double) ก็เพิ่มความปลอดภัยด้านชนิดเช่นกัน แต่จะจัดสรรออบเจ็กต์ ชนิดทึบแสงให้ความปลอดภัยแบบเดียวกันพร้อมประสิทธิภาพของชนิดพื้นฐาน
object Money:
opaque type Cents = Long
def cents(n: Long): Cents = n
extension (c: Cents)
def +(o: Cents): Cents = c + o
def value: Long = c
object Main:
def main(args: Array[String]): Unit =
val total = Money.cents(150) + Money.cents(50)
println(total.value)ควรใช้ชนิดทึบแสงเมื่อใด
ใช้ชนิดทึบแสงเมื่อคุณต้องการชนิดที่สื่อความหมายของโดเมนอย่างเข้มงวดในเส้นทางที่ทำงานบ่อยหรือคอลเลกชันขนาดใหญ่
- แยกปริมาณต่างชนิดกัน เช่น Meters กับ Seconds
- บังคับใช้เงื่อนไขที่ผ่านการตรวจสอบแล้ว
- หลีกเลี่ยงต้นทุนการจัดสรรของตัวห่อหุ้ม
object Geo:
opaque type Latitude = Double
def lat(d: Double): Option[Latitude] =
if d >= -90 && d <= 90 then Some(d) else None
extension (l: Latitude) def value: Double = l
object Main:
def main(args: Array[String]): Unit =
println(Geo.lat(41.0).map(_.value))ตรวจสอบความเข้าใจอย่างรวดเร็ว
ทดสอบความเข้าใจของคุณเกี่ยวกับชนิดทึบแสง
สรุปทบทวน
คุณได้เรียนรู้ชนิดทึบแสงของ Scala 3
opaque type X = Yซ่อนความเท่าเทียมกันนอกขอบเขต- จัดเตรียมโรงงานและเมธอด
extensionสำหรับ API - ชนิดทึบแสงที่แตกต่างกันบนชนิดพื้นฐานเดียวกันไม่สามารถใช้แทนกันได้
- ขอบเขตบนที่เป็นตัวเลือกพร้อม
<:จะเปิดเผย API เพียงบางส่วน - ไม่มีต้นทุนขณะทำงาน ต่างจากตัวห่อหุ้มแบบคลาสกรณี
object Ids:
opaque type OrderId = String
def apply(s: String): OrderId = s
extension (o: OrderId) def raw: String = o
object Main:
def main(args: Array[String]): Unit =
val id = Ids("ORD-1")
println(id.raw)คำถามที่พบบ่อย
บทเรียน “ชนิดข้อมูลทึบแสง” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “ชนิดข้อมูลทึบแสง” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ