Scala for Backend Engineering & Functional Programming · Lektion

Vereinigungs- und Schnittmengentypen

Neue Typfunktionen

Lektion 4 von 413 Schritte

Vereinigungs- und Schnittmengentypen ist eine kostenlose Scala for Backend Engineering & Functional Programming-Lektion auf CoddyKit. Dies ist Lektion 4 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.

Neue Typfeatures

Scala 3 erweitert das Typsystem um Vereinigungstypen (A | B) und Schnittmengentypen (A & B). Damit können Sie Werte präziser beschreiben, ohne Vererbungshierarchien zu benötigen.

object Main:
  def main(args: Array[String]): Unit =
    println("Union: A | B, Intersection: A & B")

Grundlagen der Vereinigungstypen

Ein Vereinigungstyp A | B bezeichnet einen Wert, der entweder ein A oder ein B ist. Er entspricht einem mengentheoretischen ODER über Typen.

object Main:
  def show(x: Int | String): String = x match
    case i: Int    => s"int $i"
    case s: String => s"str $s"

  def main(args: Array[String]): Unit =
    println(show(42))
    println(show("hi"))

Vereinigungstypen benötigen keinen gemeinsamen Supertyp

Im Gegensatz zu Scala 2 Either benötigen Vereinigungstypen kein Wrapping. Beliebige zwei Typen können vereinigt werden, ohne eine gemeinsame Elternklasse zu besitzen.

object Main:
  def parse(input: Int | Boolean): String =
    input match
      case n: Int     => s"number $n"
      case b: Boolean => s"flag $b"

  def main(args: Array[String]): Unit =
    println(parse(7))
    println(parse(true))

Vereinigungstypen zur Modellierung von Fehlern

Vereinigungstypen eignen sich für einfache Fehlerergebnisse ohne einen Wrapper-Typ. In Kombination mit Enums oder Singletons bleiben sie übersichtlich.

case object NotFound

object Main:
  def lookup(id: Int): String | NotFound.type =
    if id == 1 then "Alice" else NotFound

  def main(args: Array[String]): Unit =
    println(lookup(1))
    println(lookup(2))

Grundlagen der Schnittmengentypen

Ein Schnittmengentyp A & B bezeichnet einen Wert, der sowohl A als auch B ist. Er entspricht einem mengentheoretischen UND und wird häufig zum Kombinieren von Traits verwendet.

trait Named:
  def name: String
trait Aged:
  def age: Int

object Main:
  def describe(p: Named & Aged): String =
    s"${p.name} is ${p.age}"

  def main(args: Array[String]): Unit =
    val person = new Named with Aged:
      def name = "Bob"
      def age = 40
    println(describe(person))

Schnittmengen sind kommutativ

Bei Schnittmengentypen spielt die Reihenfolge keine Rolle: A & B ist derselbe Typ wie B & A. Das unterscheidet sich von den zusammengesetzten Typen A with B in Scala 2, bei denen die Reihenfolge bei der Auflösung mancher Member eine Rolle spielte.

trait Readable:
  def read: String
trait Writable:
  def write(s: String): Unit

object Main:
  def use(r: Readable & Writable): Unit =
    r.write("x")
    println(r.read)

  def main(args: Array[String]): Unit =
    val rw = new Readable with Writable:
      def read = "data"
      def write(s: String) = println(s"wrote $s")
    use(rw)

Mehrere Traits kombinieren

Sie können mehr als zwei Typen schneiden. Das Ergebnis erfordert alle aufgeführten Fähigkeiten.

trait A: def a: Int
trait B: def b: Int
trait C: def c: Int

object Main:
  def sum(x: A & B & C): Int = x.a + x.b + x.c

  def main(args: Array[String]): Unit =
    val v = new A with B with C:
      def a = 1
      def b = 2
      def c = 3
    println(sum(v))

Typaliase für Vereinigungstypen

Lange Vereinigungstypen können mit einem type-Alias benannt werden, damit Signaturen lesbar bleiben.

type Json = Int | String | Boolean

object Main:
  def render(j: Json): String = j match
    case i: Int     => i.toString
    case s: String  => s"\"$s\""
    case b: Boolean => b.toString

  def main(args: Array[String]): Unit =
    println(render("hi"))
    println(render(true))

Vollständiges Pattern Matching bei Vereinigungstypen

Der Compiler kennt die Elemente einer Vereinigung, sodass das Pattern Matching auf Vollständigkeit geprüft werden kann. Wenn jede Alternative behandelt wird, ist das Matching vollständig.

type Shape = "circle" | "square"

object Main:
  def sides(s: Shape): Int = s match
    case "circle" => 0
    case "square" => 4

  def main(args: Array[String]): Unit =
    println(sides("square"))

Erweiterung von Vereinigungstypen

Wenn Sie einen Vereinigungswert einer Variable mit inferiertem Typ zuweisen, behält Scala den Vereinigungstyp bei. Beachten Sie, dass manche Operationen auf die kleinste obere Schranke erweitern. Annotieren Sie den Typ daher, wenn Sie die Vereinigung erhalten möchten.

object Main:
  def pick(flag: Boolean): Int | String =
    if flag then 1 else "one"

  def main(args: Array[String]): Unit =
    val x: Int | String = pick(false)
    println(x)

Wann Sie welches verwenden sollten

Wählen Sie das passende Werkzeug.

  • Vereinigung: Ein Wert hat einen von mehreren Typen (ODER).
  • Schnittmenge: Ein Wert erfüllt mehrere Traits gleichzeitig (UND).
  • Vereinigungen vermeiden Wrapper-Typen; Schnittmengen vermeiden tiefe Vererbungshierarchien.
trait Logger: def log(s: String): Unit
trait Clock:  def now: Long

object Main:
  def run(env: Logger & Clock): Unit =
    env.log(s"time=${env.now}")

  def main(args: Array[String]): Unit =
    val env = new Logger with Clock:
      def log(s: String) = println(s)
      def now = 100L
    run(env)

Kurzer Check

Testen Sie Ihr Verständnis von Vereinigungs- und Schnittmengentypen.

Zusammenfassung

Sie haben die Vereinigungs- und Schnittmengentypen von Scala 3 kennengelernt.

  • A | B: Der Wert ist A oder B; weder ein Wrapper noch ein gemeinsamer Elternteil ist erforderlich.
  • A & B: Der Wert ist sowohl A als auch B; die Operation ist kommutativ.
  • Verengen Sie Vereinigungen per Pattern Matching; kombinieren Sie Traits mit Schnittmengen.
  • Verwenden Sie type-Aliase, um lange Vereinigungen zu benennen.
object Main:
  def length(x: String | List[Int]): Int = x match
    case s: String    => s.length
    case l: List[Int] => l.length

  def main(args: Array[String]): Unit =
    println(length("hello"))
    println(length(List(1, 2, 3)))
Kostenlos starten

Lerne Scala mit einem KI-Tutor — kostenlos

Schreibe und führe echten Code in deinem Browser aus, bekomme sofortige Hilfe von einem 24/7 KI-Tutor und setze dein Lernen im Web oder in der App fort.

Kurse
39
Lektionen
143

Häufig gestellte Fragen

Ist die Lektion „Vereinigungs- und Schnittmengentypen“ kostenlos?

Ja — der vollständige Text von „Vereinigungs- und Schnittmengentypen“ 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 „Vereinigungs- und Schnittmengentypen“?

Neue Typfunktionen 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 4 von 4.

Wie lange dauert die Lektion „Vereinigungs- und Schnittmengentypen“?

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

  1. Signifikante Einrückung
  2. Enums in Scala 3
  3. Opaque Types
  4. Vereinigungs- und Schnittmengentypen
← Zurück zu Scala for Backend Engineering & Functional Programming