Tipos unión e intersección
Nuevas características de tipos
Tipos unión e intersección es una lección gratuita de Scala for Backend Engineering & Functional Programming en CoddyKit. Esta es la lección 4 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de Scala for Backend Engineering & Functional Programming, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
Nuevas características de tipos
Scala 3 añade tipos unión (A | B) y tipos intersección (A & B) al sistema de tipos. Permiten describir los valores con mayor precisión sin jerarquías de herencia.
object Main:
def main(args: Array[String]): Unit =
println("Union: A | B, Intersection: A & B")Conceptos básicos de los tipos unión
Un tipo unión A | B representa un valor que es A o B. Es un OR de teoría de conjuntos aplicado a los tipos.
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"))Las uniones no necesitan un supertipo común
A diferencia de Either en Scala 2, los tipos unión no requieren un envoltorio. Se puede crear la unión de cualesquiera dos tipos sin que compartan una clase padre.
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))Uniones para modelar errores
Los tipos unión resultan prácticos para representar resultados de error ligeros sin un tipo envoltorio. Combinados con enums o singletons, producen código claro.
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))Conceptos básicos de los tipos intersección
Un tipo intersección A & B representa un valor que es a la vez A y B. Es un AND de teoría de conjuntos, que suele utilizarse para combinar 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))La intersección es conmutativa
El orden no importa en los tipos intersección: A & B es el mismo tipo que B & A. Esto difiere de los tipos compuestos A with B de Scala 2, que dependían del orden en algunas resoluciones de miembros.
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)Combinación de varios traits
Puede intersecar más de dos tipos. El resultado requiere todas las capacidades indicadas.
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))Aliases de tipo para uniones
Puede asignar un nombre a los tipos unión largos mediante un alias de type para mantener legibles las signaturas.
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))Coincidencia exhaustiva en uniones
El compilador conoce los miembros de una unión, por lo que puede comprobar que la coincidencia sea completa. Gestionar todas las alternativas hace que el match sea 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"))Ensanchamiento de las uniones
Al asignar un valor unión a una variable cuyo tipo se infiere, Scala conserva el tipo unión. Tenga en cuenta que algunas operaciones lo ensanchan hasta el mínimo supertipo común, así que use una anotación cuando quiera conservar la unión.
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)Cuándo usar cada uno
Elija la herramienta adecuada.
- Unión: un valor es de uno de varios tipos (OR).
- Intersección: un valor satisface varios rasgos a la vez (AND).
- Las uniones evitan los tipos envoltorio; las intersecciones evitan las jerarquías de herencia profundas.
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)Comprobación rápida
Compruebe su comprensión de los tipos unión e intersección.
Resumen
Ha aprendido los tipos unión e intersección de Scala 3.
A | B: el valor es A o B; no necesita un envoltorio ni un padre común.A & B: el valor es A y B a la vez; es conmutativo.- Use pattern matching para acotar las uniones y combine rasgos mediante intersecciones.
- Use alias de tipo con
typepara dar nombre a las uniones largas.
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)))Preguntas frecuentes
¿La lección «Tipos unión e intersección» es gratis?
Sí — el texto completo de «Tipos unión e intersección» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de Scala for Backend Engineering & Functional Programming, actualiza a CoddyKit PRO. El curso de Scala for Backend Engineering & Functional Programming incluye 4 lecciones en total.
¿Qué aprenderé en «Tipos unión e intersección»?
Nuevas características de tipos Practicas Scala for Backend Engineering & Functional Programming con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar Scala for Backend Engineering & Functional Programming?
No se requiere experiencia previa. Scala for Backend Engineering & Functional Programming en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 4 de 4.
¿Cuánto tiempo toma la lección «Tipos unión e intersección»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de Scala for Backend Engineering & Functional Programming?
Sí. Cada lección de Scala for Backend Engineering & Functional Programming incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Indentación significativa
- Enums en Scala 3
- Tipos opacos
- Tipos unión e intersección