Unionstyper och snittstyper
Nya typfunktioner
Unionstyper och snittstyper är en gratis lektion i Scala för backendutveckling och funktionell programmering på CoddyKit. Detta är lektion 4 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Scala för backendutveckling och funktionell programmering, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 4 lektioner.
Nya typfunktioner
Scala 3 lägger till uniontyper (A | B) och snitttyper (A & B) i typsystemet. De låter Er beskriva värden mer precist utan arvshierarkier.
object Main:
def main(args: Array[String]): Unit =
println("Union: A | B, Intersection: A & B")Grunderna i uniontyper
En uniontyp A | B representerar ett värde som antingen är en A eller en B. Den motsvarar ett mängdteoretiskt ELLER över typer.
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"))Unioner kräver ingen gemensam supertyp
Till skillnad från Scala 2:s Either kräver uniontyper ingen inpackning. Vilka två typer som helst kan förenas utan att ha en gemensam föräldraklass.
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))Unioner för felmodellering
Uniontyper är praktiska för enkla felresultat utan en wrapper-typ. Tillsammans med enumtyper eller singletoner blir de lättlästa.
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))Grunderna i snitttyper
En snittyp A & B representerar ett värde som är både A och B. Den motsvarar ett mängdteoretiskt OCH och används ofta för att kombinera traits.
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))Snitt är kommutativa
Ordningen spelar ingen roll för snitttyper: A & B är samma typ som B & A. Detta skiljer sig från Scala 2:s sammansatta typer A with B, där ordningen påverkade vissa medlemsupplösningar.
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)Kombinera flera traits
Ni kan ta snittet av fler än två typer. Resultatet kräver alla angivna egenskaper.
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))Typalias för unioner
Långa uniontyper kan namnges med ett type-alias för att hålla signaturerna lättlästa.
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))Fullständig mönstermatchning på unioner
Kompilatorn känner till medlemmarna i en union, så den kan kontrollera att matchningen är fullständig. När varje alternativ hanteras blir matchningen total.
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"))Breddning av unioner
När Ni tilldelar ett unionsvärde till en variabel vars typ härleds behåller Scala uniontypen. Var medveten om att vissa operationer breddar typen till den minsta övre begränsningen, så ange typen uttryckligen när Ni vill bevara unionen.
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)När de olika typerna bör användas
Välj rätt verktyg.
- Union: ett värde är en av flera typer (ELLER).
- Snitt: ett värde uppfyller flera traits samtidigt (OCH).
- Unioner undviker wrapper-typer; snitt undviker djupa arvshierarkier.
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)Snabbtest
Testa Er förståelse av uniontyper och snitttyper.
Sammanfattning
Ni har lärt Er om uniontyper och snitttyper i Scala 3.
A | B: värdet är A eller B; ingen wrapper eller gemensam förälder behövs.A & B: värdet är både A och B; kommutativt.- Använd mönstermatchning för att begränsa unioner; kombinera traits med snitt.
- Använd
type-alias för att namnge långa unioner.
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)))Lär dig Scala med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 39
- Lektioner
- 143
Vanliga frågor
Är lektionen ”Unionstyper och snittstyper” gratis?
Ja – hela texten till ”Unionstyper och snittstyper” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Scala för backendutveckling och funktionell programmering, kan Ni uppgradera till CoddyKit PRO. Kursen i Scala för backendutveckling och funktionell programmering innehåller totalt 4 lektioner.
Vad lär jag mig i ”Unionstyper och snittstyper”?
Nya typfunktioner Ni övar på Scala för backendutveckling och funktionell programmering med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Scala för backendutveckling och funktionell programmering?
Du behöver inga förkunskaper. Utbildningen i Scala för backendutveckling och funktionell programmering på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 4 av 4.
Hur lång tid tar lektionen ”Unionstyper och snittstyper”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Scala för backendutveckling och funktionell programmering-lektionen?
Ja. Varje Scala för backendutveckling och funktionell programmering-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Signifikant indentering
- Enumtyper i Scala 3
- Opaque Types
- Unionstyper och snittstyper