Tipos de patrones
Referencia de tipos de patrones en Dart.
Esta página es una referencia para los diferentes tipos de patrones. Para obtener una descripción general de cómo funcionan los patrones, dónde puedes usarlos en Dart y los casos de uso comunes, visita la página principal de Patrones (Patterns).
Precedencia de patrones
#De manera similar a la precedencia de operadores, la evaluación de patrones se rige por reglas de precedencia. Puedes utilizar patrones entre paréntesis para evaluar primero los patrones de menor precedencia.
Este documento enumera los tipos de patrones en orden ascendente de precedencia:
-
Los patrones OR lógico (logical-or) tienen menor precedencia que los AND lógicos (logical-and), los patrones AND lógicos tienen menor precedencia que los patrones relacionales, y así sucesivamente.
-
Los patrones unarios sufijos (cast, null-check, y null-assert) comparten el mismo nivel de precedencia.
-
Los patrones primarios restantes comparten la precedencia más alta. Los patrones de tipo colección (record, list y map) y los patrones Object engloban otros datos, por lo que se evalúan primero como patrones externos.
OR lógico (logical-or)
#subpattern1 || subpattern2
Un patrón OR lógico (logical-or) separa subpatrones mediante || y coincide si cualquiera de las
ramas coincide. Las ramas se evalúan de izquierda a derecha. Una vez que una rama coincide, el
resto no se evalúa.
var isPrimary = switch (color) {
Color.red || Color.yellow || Color.blue => true,
_ => false,
};
Los subpatrones en un patrón OR lógico pueden vincular variables, pero las ramas deben definir el mismo conjunto de variables, porque solo se evaluará una rama cuando coincida el patrón.
AND lógico (logical-and)
#subpattern1 && subpattern2
Un par de patrones separados por && coincide solo si ambos subpatrones coinciden. Si la
rama izquierda no coincide, la rama derecha no se evalúa.
Los subpatrones en un patrón AND lógico (logical-and) pueden vincular variables, pero las variables en cada subpatrón no deben superponerse, porque ambas se vincularán si el patrón coincide:
switch ((1, 2)) {
// Error, both subpatterns attempt to bind 'b'.
case (var a, var b) && (var b, var c): // ...
}
Relacional
#== expression
< expression
Los patrones relacionales comparan el valor coincidente con una constante dada usando cualquiera de
los operadores de igualdad o relacionales: ==, !=, <,
>, <= y >=.
El patrón coincide cuando al llamar al operador apropiado en el valor coincidente
con la constante como argumento devuelve true.
Los patrones relacionales son útiles para coincidir en rangos numéricos, especialmente cuando se combinan con el patrón AND lógico (logical-and):
String asciiCharType(int char) {
const space = 32;
const zero = 48;
const nine = 57;
return switch (char) {
< space => 'control',
== space => 'space',
> space && < zero => 'punctuation',
>= zero && <= nine => 'digit',
_ => '',
};
}
Conversión de tipo (Cast)
#foo as String
Un patrón de conversión (cast pattern) te permite insertar una conversión de tipo (type cast) en medio de la desestructuración, antes de pasar el valor a otro subpatrón:
(num, Object) record = (1, 's');
var (i as int, s as String) = record;
Los patrones de conversión (cast patterns) lanzarán una excepción (throw) si el valor no tiene el tipo indicado. Al igual que el patrón null-assert, esto te permite forzar la aserción del tipo esperado de algún valor desestructurado.
Comprobación de nulos (Null-check)
#subpattern?
Los patrones null-check coinciden primero si el valor no es nulo, y luego comparan el patrón interno contra ese mismo valor. Te permiten vincular una variable cuyo tipo es el tipo base no anulable del valor anulable que se está comparando.
Para tratar los valores null como fallos de coincidencia
sin lanzar excepciones, usa el patrón null-check.
String? maybeString = 'nullable with base type String';
switch (maybeString) {
case var s?:
// 's' has type non-nullable String here.
}
Para coincidir cuando el valor sea null, usa el patrón constante null.
Aserción de nulos (Null-assert)
#subpattern!
Los patrones null-assert coinciden primero si el objeto no es nulo, y luego en el valor. Permiten que los valores no nulos fluyan, pero lanzan una excepción si el valor coincidente es nulo.
Para asegurarse de que los valores null no se traten silenciosamente como fallos de coincidencia,
usa un patrón null-assert al comparar:
List<String?> row = ['user', null];
switch (row) {
case ['user', var name!]: // ...
// 'name' is a non-nullable string here.
}
Para eliminar valores null de los patrones de declaración de variables,
usa el patrón null-assert:
(int?, int?) position = (2, 3);
var (x!, y!) = position;
Para coincidir cuando el valor sea null, usa el patrón constante null.
Constante
#123, null, 'string', math.pi, SomeClass.constant, const Thing(1, 2), const (1 + 2)
Los patrones constantes coinciden cuando el valor es igual a la constante:
switch (number) {
// Matches if 1 == number.
case 1: // ...
}
Puedes usar literales simples y referencias a constantes nombradas directamente como patrones constantes:
- Literales numéricos (
123,45.56) - Literales booleanos (
true) - Literales de cadena (String literals) (
'string') - Constantes nombradas (
someConstant,math.pi,double.infinity) - Constructores constantes (
const Point(0, 0)) - Literales de colección constantes (
const [],const {1, 2})
Las expresiones constantes más complejas deben estar entre paréntesis y llevar el prefijo
const (const (1 + 2)):
// List or map pattern:
case [a, b]: // ...
// List or map literal:
case const [a, b]: // ...
Variable
#var bar, String str, final int _
Los patrones de variables vinculan nuevas variables a valores que han coincidido o se han desestructurado. Por lo general, ocurren como parte de un patrón de desestructuración (destructuring pattern) para capturar un valor desestructurado.
Las variables están dentro del alcance en una región de código que solo es accesible cuando el patrón ha coincidido.
switch ((1, 2)) {
// 'var a' and 'var b' are variable patterns that bind to 1 and 2, respectively.
case (var a, var b): // ...
// 'a' and 'b' are in scope in the case body.
}
Un patrón de variable con tipo (typed) solo coincide si el valor coincidente tiene el tipo declarado, y falla en caso contrario:
switch ((1, 2)) {
// Does not match.
case (int a, String b): // ...
}
Puedes usar un patrón comodín (wildcard pattern) como un patrón de variable.
Identificador
#foo, _
Los patrones de identificador se comportan como un patrón constante o como un patrón de variable, dependiendo del contexto donde aparezcan:
- Contexto de declaración (Declaration): declara una nueva variable con el nombre del identificador:
var (a, b) = (1, 2); - Contexto de asignación (Assignment): asigna a una variable existente con el nombre del identificador:
(a, b) = (3, 4); -
Coincidencia context: treated as a named constant pattern (unless its name is
_):dartconst c = 1; switch (2) { case c: print('match $c'); default: print('no match'); // Prints "no match". } - Identificador comodín (Wildcard) en cualquier contexto: coincide con cualquier valor y lo descarta:
case [_, var y, _]: print('El elemento del medio es $y');
Entre paréntesis
#(subpattern)
Al igual que las expresiones entre paréntesis, los paréntesis en un patrón te permiten controlar la precedencia de patrones e insertar un patrón de menor precedencia donde se espera uno de mayor precedencia.
Por ejemplo, imagina que las constantes booleanas x, y y z
son iguales a true, true y false, respectivamente.
Aunque el siguiente ejemplo se asemeja a la evaluación de expresiones booleanas,
el ejemplo compara patrones.
// ...
x || y => 'matches true',
x || y && z => 'matches true',
x || (y && z) => 'matches true',
// `x || y && z` is the same thing as `x || (y && z)`.
(x || y) && z => 'matches nothing',
// ...
Dart comienza a comparar el patrón de izquierda a derecha.
El primer patrón coincide con
trueya quexcoincide contrue.El segundo patrón coincide con
trueya quexcoincide contrue.El tercer patrón coincide con
trueya quexcoincide contrue.-
El cuarto patrón
(x || y) && zno tiene coincidencia.- El
xcoincide contrue, por lo que Dart no intenta coincidir cony. - Aunque
(x || y)coincide contrue,zno coincide contrue - Por lo tanto, el patrón
(x || y) && zno coincide contrue. - El subpatrón
(x || y)no coincide confalse, por lo que Dart no intenta coincidir conz. - Por lo tanto, el patrón
(x || y) && zno coincide confalse. - Como conclusión,
(x || y) && zno tiene coincidencia.
- El
Lista
#[subpattern1, subpattern2]
Un patrón de lista coincide con valores que implementan List, y luego compara recursivamente
sus subpatrones contra los elementos de la lista para desestructurarlos por posición:
const a = 'a';
const b = 'b';
switch (obj) {
// List pattern [a, b] matches obj first if obj is a list with two fields,
// then if its fields match the constant subpatterns 'a' and 'b'.
case [a, b]:
print('$a, $b');
}
Los patrones de lista requieren que el número de elementos en el patrón coincida con la lista completa. Sin embargo, puedes usar un elemento restante (rest element) como marcador de posición para representar cualquier número de elementos en una lista.
Elemento restante (Rest element)
#Los patrones de lista pueden contener un elemento restante (...) lo que permite la coincidencia con listas
de longitudes arbitrarias.
var [a, b, ..., c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 6 7".
print('$a $b $c $d');
Un elemento restante también puede tener un subpatrón que recopila los elementos que no coinciden con los otros subpatrones de la lista, en una nueva lista:
var [a, b, ...rest, c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 [3, 4, 5] 6 7".
print('$a $b $rest $c $d');
Mapa
#{"key": subpattern1, someConst: subpattern2}
Los patrones de mapa coinciden con valores que implementan Map, y luego comparan recursivamente
sus subpatrones contra las claves del mapa para desestructurarlos.
Los patrones de mapa no requieren que el patrón coincida con el mapa completo. Un patrón de mapa
ignora cualquier clave que contenga el mapa que no coincida con el patrón.
Intentar coincidir con una clave que no existe en el mapa
lanzará un StateError:
final {'foo': int? foo} = {};
Registro (Record)
#(subpattern1, subpattern2)
(x: subpattern1, y: subpattern2)
Los patrones de registro (record) coinciden con un objeto registro (record) y desestructuran sus campos. Si el valor no es un registro con la misma forma (shape) que el patrón, la coincidencia falla. De lo contrario, los subpatrones de campo se comparan con los campos correspondientes en el registro.
Los patrones de registro requieren que el patrón coincida con el registro completo. Para desestructurar un registro con campos nombrados usando un patrón, incluye los nombres de los campos en el patrón:
var (myString: foo, myNumber: bar) = (myString: 'string', myNumber: 1);
El nombre del getter se puede omitir e inferir a partir del patrón de variable o patrón de identificador en el subpatrón de campo. Cada uno de estos pares de patrones es equivalente:
// Record pattern with variable subpatterns:
var (untyped: untyped, typed: int typed) = record;
var (:untyped, :int typed) = record;
switch (record) {
case (untyped: var untyped, typed: int typed): // ...
case (:var untyped, :int typed): // ...
}
// Record pattern with null-check and null-assert subpatterns:
switch (record) {
case (checked: var checked?, asserted: var asserted!): // ...
case (:var checked?, :var asserted!): // ...
}
// Record pattern with cast subpattern:
var (untyped: untyped as int, typed: typed as String) = record;
var (:untyped as int, :typed as String) = record;
Object
#SomeClass(x: subpattern1, y: subpattern2)
Los patrones de objeto (Object patterns) comprueban el valor coincidente contra un tipo con nombre dado para desestructurar datos usando getters en las propiedades del objeto. Se refutanPatrón refutableUn patrón que se puede probar contra un valor. Más información si el valor no tiene el mismo tipo.
switch (shape) {
// Matches if shape is of type Rect, and then against the properties of Rect.
case Rect(width: var w, height: var h): // ...
}
El nombre del getter se puede omitir e inferir del patrón de variable o patrón de identificador en el subpatrón de campo:
// Binds new variables x and y to the values of Point's x and y properties.
var Point(:x, :y) = Point(1, 2);
Los patrones de objeto no requieren que el patrón coincida con todo el objeto. Si un objeto tiene campos adicionales que el patrón no desestructura, aún puede coincidir.
Comodín (Wildcard)
#_
Un patrón llamado _ es un comodín (wildcard), ya sea un patrón de variable o
patrón de identificador, que no vincula ni asigna a ninguna variable.
Es útil como marcador de posición en lugares donde necesitas un subpatrón para desestructurar valores posicionales posteriores:
var list = [1, 2, 3];
var [_, two, _] = list;
Un nombre comodín con una anotación de tipo es útil cuando deseas probar el tipo de un valor pero no vincular el valor a un nombre:
switch (record) {
case (int _, String _):
print('First field is int and second is String.');
}
A menos que se indique lo contrario, la documentación en este sitio refleja Dart 3.12.2. Página actualizada por última vez el 2026-05-15. Ver fuente oreportar un problema.