invalid_ case_ patterns
Saiba mais sobre a regra de lint invalid_case_patterns.
Use expressões case válidas no Dart 3.0.
Detalhes
#Algumas expressões case que são válidas no Dart 2.19 e anteriores passarão a gerar erro ou terão a semântica alterada quando uma biblioteca for atualizada para o Dart 3.0. Esta lint sinaliza essas expressões para facilitar a migração para o Dart 3.0.
Algumas cases de switch válidas no 2.19 passarão a ser erros de compilação no Dart 3.0:
- Literais de conjunto
- Expressões entre parênteses
- Chamadas a
identical(). -
Expressões com operadores unários
!,-ou~(exceto-antes de um literal inteiro, que é um padrão válido e está tudo bem) -
Expressões com operadores binários
!=,==,&,|,^,~/,>>,>>>,<<,+,-,*,/,%,<,<=,>,>=,??. - Operador condicional
?: - Chamadas
.lengthem strings - Expressões
iseis!
Exemplos de todos eles:
switch (obj) {
case {1}: // Set literal.
case (1): // Parenthesized expression.
case identical(1, 2): // `identical()` call.
case -pi: // Unary operator.
case 1 + 2: // Binary operator.
case true ? 1 : 2: // Conditional operator.
case 'hi'.length: // .length call.
case i is int: // is expression.
}
Algumas cases de switch válidas no 2.19 também são padrões sintaticamente válidos, mas o comportamento de pattern matching pode ser diferente do comportamento atual de igualdade de constantes. São elas:
Literais de lista e de mapa. Um literal de lista ou de mapa pode aparecer como constante em um case:
switch (obj) {
case [1, 2]: ...
case {'k': 'v'}: ...
}
Atualmente, o case só dará match se o valor recebido tiver a mesma identidade da constante. Assim:
test(List<int> list) {
switch (list) {
case [1, 2]: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const [1, 2]); // Prints "Matched".
test([1, 2]); // Prints "Did not match".
}
Com padrões, um literal de lista ou de mapa se torna um padrão de lista ou de mapa. O padrão desestrutura o objeto recebido e dá match se todos os subpadrões derem match. Em outras palavras, o match de padrões de lista e de mapa usa algo mais parecido com igualdade profunda.
Com o Dart 3.0, o programa acima imprime "Matched" duas vezes.
Chamadas de construtor constante. De forma semelhante às coleções, você pode construir uma instância constante de uma classe em um case:
class Point {
final int x;
final int y;
const Point({this.x, this.y});
}
test(Point p) {
switch (p) {
case Point(x: 1, y: 2): print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const Point(1, 2)); // Prints "Matched".
test(Point(1, 2)); // Prints "Did not match".
}
Novamente, como nas coleções, o case atualmente só dá match se o valor recebido tiver a mesma identidade. Com padrões, a sintaxe
Point(...) se torna um padrão de objeto que desestrutura o ponto recebido, chama os getters
x e y nele e então compara os resultados com os subpadrões correspondentes.
Neste exemplo, ele imprimirá "Matched" duas vezes.
Observe que padrões de objeto suportam apenas campos nomeados. Assim, qualquer construtor constante usado em um case hoje com argumentos posicionais se tornará um erro de compilação quando for interpretado como padrão. Uma chamada de construtor constante sem argumentos é um padrão de objeto válido e faz apenas um teste de tipo:
class Thing {
const Thing();
}
test(Thing t) {
switch (t) {
case Thing(): print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(const Thing()); // Prints "Matched".
test(Thing()); // Prints "Did not match".
}
Quando interpretado como padrão, isso imprime "Matched" duas vezes.
Curingas. Hoje, você pode ter uma constante chamada _:
test(int n) {
const _ = 3;
switch (n) {
case _: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(3); // Prints "Matched".
test(5); // Prints "Did not match".
}
Com padrões, o identificador _ é tratado como um padrão que dá match em todos os valores, então isso imprime "Matched" duas vezes.
Operadores lógicos. Os operadores lógicos && e || são expressões constantes válidas e também padrões válidos. Como expressão constante, eles simplesmente avaliam a expressão para um booleano e dão match se o valor recebido for igual a esse valor booleano. Assim:
test(bool b) {
switch (b) {
case true && false: print('Matched'); break;
default: print('Did not match'); break;
}
}
main() {
test(false); // Prints "Matched".
test(true); // Prints "Did not match".
}
Com o Dart 3.0, eles se tornam padrões. O exemplo acima imprime "Did not match" duas vezes, porque nenhum valor booleano pode ser verdadeiro e falso ao mesmo tempo.
Muitos dos casos inválidos podem ser alterados mecanicamente para algo que é válido tanto no Dart atual quanto no Dart 3.0, e que tem o mesmo significado.
Expressões entre parênteses: desde que a expressão interna não seja uma que quebre no Dart 3.0, basta remover os parênteses.
Literais de lista, literais de mapa, literais de conjunto e chamadas de construtor constante:
coloque const antes do literal ou da chamada. Isso o transforma em um padrão constante, o que preserva o comportamento atual:
RUIM:
case [1, 2]:
case {'k': 'v'}:
case {1, 2}:
case Point(1, 2):
BOM:
case const [1, 2]:
case const {'k': 'v'}:
case const {1, 2}:
case const Point(1, 2):
-
Curingas: renomeie a constante de
_para outro nome. Como o nome é privado, isso pode ser feito localmente na biblioteca, sem afetar outro código. -
Todo o resto: para qualquer outra expressão inválida, é preciso extrair a expressão para uma nova constante nomeada. Por exemplo, se você tiver um código como este:
RUIM:
switch (n) {
case 1 + 2: ...
}
Pode ser corrigido alterando para:
BOM:
const three = 1 + 2;
switch (n) {
case three: ...
}
Ativar
#
Para ativar a regra invalid_case_patterns, adicione invalid_case_patterns em
linter > rules no seu arquivo analysis_options.yaml:
linter:
rules:
- invalid_case_patterns
Se você usa a sintaxe de mapa YAML para configurar as regras de lint,
adicione invalid_case_patterns: true em linter > rules:
linter:
rules:
invalid_case_patterns: true
Salvo indicação em contrário, a documentação neste site reflete Dart 3.13.7. 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ê.