Instanzen definieren
Implizite Instanzen
Instanzen definieren ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 2 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Scala for Backend Engineering & Functional Programming-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Instanzen definieren
Eine Instanz teilt dem Compiler mit, wie sich eine Typklasse für einen bestimmten Typ verhält. In Scala werden Instanzen normalerweise mit implicit (Scala 2) markiert oder mit given (Scala 3) deklariert, damit sie automatisch gefunden werden.
Eine implizite val-Instanz
Für eine einfache Typklasse genügt ein implicit val. Der Compiler findet ihn, wenn eine Funktion ein Show[Int] benötigt.
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: Eine Instanz abrufen
implicitly[Show[Int]] weist den Compiler an, die im Gültigkeitsbereich vorhandene Instanz abzurufen. Das ist nützlich, um zu testen, ob eine Instanz existiert, oder um direkt auf sie zuzugreifen.
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))
}
}Instanzen für eigene Typen
Definieren Sie eine Instanz für Ihre eigene Case-Klasse. Die Datenklasse bleibt übersichtlich; die Formatierung befindet sich in der Instanz.
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 für generische Instanzen
Wenn eine Instanz von einer anderen Instanz abhängt, verwenden Sie implicit def. Hier wird ein Show[List[A]] aus einem Show[A] erstellt.
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)))
}
}Instanzen im Companion-Objekt
Wenn Sie Instanzen im Companion-Objekt der Typklasse platzieren, werden sie automatisch und ohne Import gefunden. Das ist der empfohlene Ort für Standardinstanzen.
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"))
}
}Gültigkeitsbereich und Priorität impliziter Werte
Der Compiler sucht an mehreren Stellen nach einer Instanz: zuerst im lokalen beziehungsweise importierten Gültigkeitsbereich, danach in den Companion-Objekten der beteiligten Typen. Sind zwei Instanzen gleich spezifisch, erhalten Sie einen Fehler wegen eines mehrdeutigen impliziten Werts.
Kurzschreibweise für Context Bounds
Die Syntax def f[A: Show](a: A) ist ein Context Bound: Sie bedeutet, dass ein implizites Show[A] im Gültigkeitsbereich vorhanden sein muss. Rufen Sie es innerhalb der Funktion mit implicitly ab.
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))
}
}Eine Hilfsfunktion zum Abrufen
Bibliotheken ergänzen das Companion-Objekt um eine apply-Methode als praktischen Summoner: Show[Int] gibt die Instanz zurück. Das ist übersichtlicher als 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))
}
}Verwaiste Instanzen vermeiden
Eine verwaiste Instanz ist eine Instanz, die weder zusammen mit der Typklasse noch zusammen mit dem Typ definiert ist. Sie ist zwar zulässig, kann aber über verschiedene Imports hinweg zu inkonsistentem Verhalten führen. Bevorzugen Sie Instanzen in Companion-Objekten, damit sie konsistent bleiben.
Alles zusammenführen
Ein vollständiges Programm mit Instanzen im Companion-Objekt, einer abgeleiteten Listeninstanz und einem Summoner.
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)))
}
}Kurze Überprüfung
Testen Sie Ihr Wissen über das Definieren von Instanzen.
Zusammenfassung
Sie haben gelernt, Instanzen zu definieren:
implicit valfür einfache Instanzen,implicit deffür abgeleitete Instanzen.- Rufen Sie Instanzen mit
implicitlyoder einemapplyim Companion-Objekt ab. - Verwenden Sie Context Bounds
[A: Show]als Kurzschreibweise. - Platzieren Sie Instanzen in Companion-Objekten, um verwaiste Instanzen zu vermeiden.
Häufig gestellte Fragen
Ist die Lektion „Instanzen definieren“ kostenlos?
Ja — der vollständige Text von „Instanzen definieren“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Scala for Backend Engineering & Functional Programming-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Scala for Backend Engineering & Functional Programming-Kurs umfasst insgesamt 4 Lektionen.
Was lerne ich in „Instanzen definieren“?
Implizite Instanzen Du übst Scala for Backend Engineering & Functional Programming mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.
Brauche ich Erfahrung, um Scala for Backend Engineering & Functional Programming zu starten?
Keine Vorkenntnisse erforderlich. Scala for Backend Engineering & Functional Programming auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 2 von 4.
Wie lange dauert die Lektion „Instanzen definieren“?
Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.
Kann ich in dieser Scala for Backend Engineering & Functional Programming-Lektion Code schreiben und ausführen?
Ja. Jede Scala for Backend Engineering & Functional Programming-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.
Alle Lektionen in diesem Kurs
- Das Type-Class-Muster
- Instanzen definieren
- Gängige Typeclasses
- Ableitung von Typeclasses