Tipe Opaque
Abstraksi tanpa biaya tambahan
Tipe Opaque adalah pelajaran Scala for Backend Engineering & Functional Programming gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Scala for Backend Engineering & Functional Programming, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.
Apa Itu Tipe Opaque?
Tipe opaque adalah fitur Scala 3 untuk membuat abstraksi tanpa biaya. Tipe ini memberikan tipe berbeda pada waktu kompilasi, tetapi dikompilasi menjadi tipe dasar tanpa pembungkusan saat runtime.
- Keamanan tipe seperti pada class pembungkus.
- Tidak ada overhead alokasi.
object Distances:
opaque type Meters = Double
object Main:
def main(args: Array[String]): Unit =
println("Opaque types compile to their underlying type")Mendeklarasikan Tipe Opaque
Deklarasikan tipe opaque di dalam objek atau class. Di luar cakupan tersebut, Meters dan Double diperlakukan sebagai tipe yang berbeda.
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))Batas Opasitas
Di dalam cakupan pendefinisiannya, tipe opaque dan tipe dasarnya dapat saling dipertukarkan. Di luar, hanya tipe opaque yang terlihat, sehingga Anda tidak dapat secara tidak sengaja meneruskan Double mentah ketika Meters diperlukan.
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))Menambahkan Metode Ekstensi
Berikan perilaku pada tipe opaque dengan metode ekstensi yang didefinisikan dalam cakupan yang sama. Pemanggil mendapatkan operasi yang praktis tanpa mengekspos tipe dasarnya.
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)Mencegah Kekeliruan Tipe
Keuntungan utamanya: dua tipe opaque yang menggunakan tipe dasar sama tetap tidak kompatibel. Meters tidak dapat tertukar dengan Kilometers, meskipun keduanya merupakan 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))Tipe Opaque dengan Batasan
Anda dapat memberikan batas atas pada tipe opaque dengan <:. Ini mengekspos sebagian API publik sambil menyembunyikan representasi persisnya.
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)Konstruksi Cerdas dengan Validasi
Gabungkan tipe opaque dengan factory yang melakukan validasi untuk memastikan nilainya selalu valid. Konstruktor tetap privat; hanya factory yang telah divalidasi yang bersifat publik.
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))Tanpa Biaya Saat Runtime
Berbeda dari pembungkus value class atau case class, tipe opaque tidak membuat objek apa pun saat runtime. List berisi Meters secara harfiah merupakan list berisi double di JVM, sehingga tidak ada boxing.
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)Tipe Opaque vs Alias Tipe
Alias type X = Y biasa bersifat transparan: X dan Y sepenuhnya dapat dipertukarkan di mana pun. Tipe opaque menyembunyikan kesetaraan tersebut di luar cakupannya, sehingga memberikan keamanan tipe yang nyata.
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)Tipe Opaque vs Pembungkus Case Class
Pembungkus case class seperti case class Meters(value: Double) juga menambahkan keamanan tipe, tetapi mengalokasikan sebuah objek. Tipe opaque memberikan keamanan yang sama dengan kinerja tipe mentah.
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)Kapan Menggunakan Tipe Opaque
Gunakan tipe opaque ketika Anda menginginkan pengetikan domain yang kuat pada jalur yang sering dijalankan atau koleksi berukuran besar.
- Membedakan kuantitas (Meters vs Seconds).
- Menegakkan invariant yang telah divalidasi.
- Menghindari biaya alokasi pembungkus.
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))Pemeriksaan Singkat
Uji pemahaman Anda tentang tipe opaque.
Ringkasan
Anda telah mempelajari tipe opaque Scala 3.
opaque type X = Ymenyembunyikan kesetaraan di luar cakupannya.- Sediakan factory dan metode
extensionuntuk API. - Tipe opaque yang berbeda di atas tipe dasar yang sama tidak kompatibel.
- Batas atas opsional dengan
<:mengekspos sebagian API. - Tidak ada biaya saat runtime, berbeda dari pembungkus case class.
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)Pertanyaan yang Sering Diajukan
Apakah pelajaran “Tipe Opaque” gratis?
Ya — teks lengkap “Tipe Opaque” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Scala for Backend Engineering & Functional Programming, upgrade ke CoddyKit PRO. Kursus Scala for Backend Engineering & Functional Programming mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Tipe Opaque”?
Abstraksi tanpa biaya tambahan Kamu berlatih Scala for Backend Engineering & Functional Programming dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Scala for Backend Engineering & Functional Programming?
Tidak diperlukan pengalaman sebelumnya. Scala for Backend Engineering & Functional Programming di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Tipe Opaque” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Scala for Backend Engineering & Functional Programming ini?
Ya. Setiap pelajaran Scala for Backend Engineering & Functional Programming menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.