Tipos de pattern
Referência de tipos de pattern em Dart.
Esta página é uma referência para os diferentes tipos de patterns. Para uma visão geral de como patterns funcionam, onde você pode usá-los em Dart e casos de uso comuns, visite a página principal de Patterns.
Precedência de patterns
#Similar à precedência de operadores, a avaliação de patterns segue regras de precedência. Você pode usar patterns entre parênteses para avaliar patterns de menor precedência primeiro.
Este documento lista os tipos de pattern em ordem crescente de precedência:
-
Patterns Logical-or têm menor precedência que logical-and, patterns logical-and têm menor precedência que patterns relational, e assim por diante.
-
Patterns unários pós-fixados (cast, null-check, e null-assert) compartilham o mesmo nível de precedência.
-
Os patterns primários restantes compartilham a maior precedência. Patterns de tipo coleção (record, list e map) e patterns Object englobam outros dados, então são avaliados primeiro como patterns externos.
Logical-or
#subpattern1 || subpattern2
Um pattern logical-or separa subpatterns por || e corresponde se qualquer um dos
ramos corresponder. Os ramos são avaliados da esquerda para a direita. Uma vez que um ramo corresponde, os
demais não são avaliados.
var isPrimary = switch (color) {
Color.red || Color.yellow || Color.blue => true,
_ => false,
};
Subpatterns em um pattern logical-or podem vincular variáveis, mas os ramos devem definir o mesmo conjunto de variáveis, porque apenas um ramo será avaliado quando o pattern corresponder.
Logical-and
#subpattern1 && subpattern2
Um par de patterns separados por && corresponde apenas se ambos os subpatterns corresponderem. Se o
ramo esquerdo não corresponder, o ramo direito não é avaliado.
Subpatterns em um pattern logical-and podem vincular variáveis, mas as variáveis em cada subpattern não devem se sobrepor, porque ambas serão vinculadas se o pattern corresponder:
switch ((1, 2)) {
// Error, both subpatterns attempt to bind 'b'.
case (var a, var b) && (var b, var c): // ...
}
Relational
#== expression
< expression
Patterns relacionais comparam o valor correspondido com uma constante fornecida usando qualquer um dos
operadores de igualdade ou relacionais: ==, !=, <,
>, <= e >=.
O pattern corresponde quando chamar o operador apropriado no valor correspondido
com a constante como argumento retorna true.
Patterns relacionais são úteis para corresponder em intervalos numéricos, especialmente quando combinados com o pattern 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',
_ => '',
};
}
Cast
#foo as String
Um pattern cast permite inserir um type cast no meio da desestruturação, antes de passar o valor para outro subpattern:
(num, Object) record = (1, 's');
var (i as int, s as String) = record;
Patterns cast irão lançar uma exceção se o valor não tiver o tipo declarado. Como o pattern null-assert, isso permite afirmar forçadamente o tipo esperado de algum valor desestruturado.
Null-check
#subpattern?
Patterns null-check correspondem primeiro se o valor não for null, e então correspondem ao pattern interno contra esse mesmo valor. Eles permitem vincular uma variável cujo tipo é o tipo base não-nulo do valor nulo sendo correspondido.
Para tratar valores null como falhas de correspondência
sem lançar exceção, use o pattern null-check.
String? maybeString = 'nullable with base type String';
switch (maybeString) {
case var s?:
// 's' has type non-nullable String here.
}
Para corresponder quando o valor é null, use o pattern constant null.
Null-assert
#subpattern!
Patterns null-assert correspondem primeiro se o objeto não for null, então no valor. Eles permitem que valores não-nulos fluam, mas lançam exceção se o valor correspondido for null.
Para garantir que valores null não sejam silenciosamente tratados como falhas de correspondência,
use um pattern null-assert ao corresponder:
List<String?> row = ['user', null];
switch (row) {
case ['user', var name!]: // ...
// 'name' is a non-nullable string here.
}
Para eliminar valores null de patterns de declaração de variáveis,
use o pattern null-assert:
(int?, int?) position = (2, 3);
var (x!, y!) = position;
Para corresponder quando o valor é null, use o pattern constant null.
Constant
#123, null, 'string', math.pi, SomeClass.constant, const Thing(1, 2), const (1 + 2)
Patterns constant correspondem quando o valor é igual à constante:
switch (number) {
// Matches if 1 == number.
case 1: // ...
}
Você pode usar literais simples e referências a constantes nomeadas diretamente como patterns constant:
- Literais numéricos (
123,45.56) - Literais booleanos (
true) - Literais de string (
'string') - Constantes nomeadas (
someConstant,math.pi,double.infinity) - Construtores constant (
const Point(0, 0)) - Literais de coleção constant (
const [],const {1, 2})
Expressões constant mais complexas devem estar entre parênteses e prefixadas com
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 _
Patterns variable vinculam novas variáveis a valores que foram correspondidos ou desestruturados. Eles geralmente ocorrem como parte de um pattern de desestruturação para capturar um valor desestruturado.
As variáveis estão no escopo em uma região de código que só é alcançável quando o pattern corresponde.
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.
}
Um pattern variable tipado só corresponde se o valor correspondido tiver o tipo declarado, e falha caso contrário:
switch ((1, 2)) {
// Does not match.
case (int a, String b): // ...
}
Você pode usar um pattern wildcard como um pattern variable.
Identifier
#foo, _
Patterns identifier podem se comportar como um pattern constant ou como um pattern variable, dependendo do contexto onde aparecem:
-
Contexto de declaração: declara uma nova variável com nome identificador:
var (a, b) = (1, 2); -
Contexto de atribuição: atribui a uma variável existente com nome identificador:
(a, b) = (3, 4); -
Contexto de correspondência: tratado como um pattern constant nomeado (a menos que seu nome seja
_):dartconst c = 1; switch (2) { case c: print('match $c'); default: print('no match'); // Prints "no match". } -
Identificador wildcard em qualquer contexto: corresponde a qualquer valor e o descarta:
case [_, var y, _]: print('The middle element is $y');
Parenthesized
#(subpattern)
Como expressões entre parênteses, parênteses em um pattern permitem controlar a precedência do pattern e inserir um pattern de menor precedência onde um de maior precedência é esperado.
Por exemplo, imagine que as constantes booleanas x, y e z
sejam iguais a true, true e false, respectivamente.
Embora o exemplo a seguir se assemelhe à avaliação de expressões booleanas,
o exemplo corresponde patterns.
// ...
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 começa a corresponder o pattern da esquerda para a direita.
-
O primeiro pattern corresponde a
truepoisxcorresponde atrue. -
O segundo pattern corresponde a
truepoisxcorresponde atrue. -
O terceiro pattern corresponde a
truepoisxcorresponde atrue. -
O quarto pattern
(x || y) && znão tem correspondência.- O
xcorresponde atrue, então Dart não tenta correspondery. - Embora
(x || y)corresponda atrue,znão corresponde atrue - Portanto, o pattern
(x || y) && znão corresponde atrue. - O subpattern
(x || y)não corresponde afalse, então Dart não tenta corresponderz. - Portanto, o pattern
(x || y) && znão corresponde afalse. - Como conclusão,
(x || y) && znão tem correspondência.
- O
List
#[subpattern1, subpattern2]
Um pattern list corresponde a valores que implementam List, e então recursivamente
corresponde seus subpatterns aos elementos da lista para desestruturá-los por posição:
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');
}
Patterns list requerem que o número de elementos no pattern corresponda à lista inteira. Você pode, no entanto, usar um elemento rest como um espaço reservado para contabilizar qualquer número de elementos em uma lista.
Elemento rest
#
Patterns list podem conter um elemento rest (...) que permite corresponder listas
de comprimentos arbitrários.
var [a, b, ..., c, d] = [1, 2, 3, 4, 5, 6, 7];
// Prints "1 2 6 7".
print('$a $b $c $d');
Um elemento rest também pode ter um subpattern que coleta elementos que não correspondem aos outros subpatterns na lista, em uma nova 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');
Map
#{"key": subpattern1, someConst: subpattern2}
Patterns map correspondem a valores que implementam Map, e então recursivamente
correspondem seus subpatterns às chaves do map para desestruturá-los.
Patterns map não requerem que o pattern corresponda ao map inteiro. Um pattern map
ignora quaisquer chaves que o map contenha que não são correspondidas pelo pattern.
Tentar corresponder uma chave que não existe no map irá
lançar um StateError:
final {'foo': int? foo} = {};
Record
#(subpattern1, subpattern2)
(x: subpattern1, y: subpattern2)
Patterns record correspondem a um objeto record e desestrutura seus campos. Se o valor não for um record com a mesma forma do pattern, a correspondência falha. Caso contrário, os subpatterns de campo são correspondidos aos campos correspondentes no record.
Patterns record requerem que o pattern corresponda ao record inteiro. Para desestruturar um record com campos nomeados usando um pattern, inclua os nomes dos campos no pattern:
var (myString: foo, myNumber: bar) = (myString: 'string', myNumber: 1);
O nome do getter pode ser omitido e inferido do pattern variable ou pattern identifier no subpattern de campo. Esses pares de patterns são equivalentes:
// 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)
Patterns object verificam o valor correspondido contra um tipo nomeado fornecido para desestruturar dados usando getters nas propriedades do objeto. Eles são refutadosRefutable patternUm padrão que pode ser testado contra um valor. Saiba mais se o valor não tiver o mesmo 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): // ...
}
O nome do getter pode ser omitido e inferido do pattern variable ou pattern identifier no subpattern 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);
Patterns object não requerem que o pattern corresponda ao objeto inteiro. Se um objeto tiver campos extras que o pattern não desestrutura, ele ainda pode corresponder.
Wildcard
#_
Um pattern chamado _ é um wildcard, seja um pattern variable ou
pattern identifier, que não vincula ou atribui a nenhuma variável.
É útil como um espaço reservado em lugares onde você precisa de um subpattern para desestruturar valores posicionais posteriores:
var list = [1, 2, 3];
var [_, two, _] = list;
Um nome wildcard com uma anotação de tipo é útil quando você deseja testar o tipo de um valor mas não vincular o valor a um nome:
switch (record) {
case (int _, String _):
print('First field is int and second is String.');
}
Salvo indicação em contrário, a documentação neste site reflete Dart 3.13.7. Página atualizada pela última vez em 2026-11-12. Ver código-fonte ou relatar um problema.
Encontrou essa página sem tradução ou que precisa de correção? Abra uma issue e nos ajude a manter esse site em PT-BR para ajudar pessoas como você.