Pular para o conteúdo principal

unsafe_variance

Detalhes sobre o diagnóstico 'unsafe_variance' produzido pelo analisador do Dart.

This type is unsafe: a type parameter occurs in a non-covariant position.

Descrição

#

O analisador gera este diagnóstico quando um membro de instância tem um tipo de resultado que é contravariante ou invariante em um parâmetro de tipo da declaração que o contém. O tipo de resultado de uma variável é o seu tipo, e o tipo de resultado de um getter ou de um método é o seu tipo de retorno. Esta regra alerta contra esses membros porque é provável que eles causem uma verificação de tipo que falha em tempo de execução, sem nenhum aviso ou erro estático no ponto de chamada.

Exemplo

#

O código a seguir gera este diagnóstico porque X aparece como tipo de parâmetro no tipo de f, o que é uma ocorrência contravariante desse parâmetro de tipo:

dart
class C<X> {
  final bool Function(X) f;
  C(this.f);
}

Isso é inseguro: se c tem tipo estático C<num> e tipo de tempo de execução C<int>, então c.f vai lançar uma exceção. Logo, toda invocação c.f(a) também vai lançar uma exceção, mesmo no caso em que a tem o tipo correto como argumento de c.f.

Correções comuns

#

Se o membro marcado é privado ou pode ser tornado privado, talvez você consiga garantir que ele nunca seja acessado por outro receptor que não seja this. Isso é suficiente para garantir que o erro de tipo em tempo de execução não aconteça. Por exemplo:

dart
class C<X> {
  // NB: Ensure manually that `_f` is only accessed on `this`.
  // ignore: unsafe_variance
  final bool Function(X) _f;
​
  C(this._f);
​
  // We can write a forwarding method to allow clients to call `_f`.
  bool f(X x) => _f(x);
}

Você pode eliminar a variância insegura usando um tipo mais geral para o membro marcado. Nesse caso, talvez seja necessário verificar o tipo em tempo de execução e fazer um downcast nos pontos de chamada.

dart
class C<X> {
  final bool Function(Never) f;
  C(this.f);
}

Se c tem tipo estático C<num>, então você pode testar o tipo. Por exemplo, c.f is bool Function(num). Você pode chamá-lo com segurança com um argumento do tipo num, se ele tiver esse tipo.

Você também pode eliminar a variância insegura usando um tipo bem mais geral, como Function, que é essencialmente o tipo dynamic para funções.

dart
class C<X> {
  final Function f;
  C(this.f);
}

Isso torna c.f(a) seguro em tempo de execução: ele lança uma exceção se e somente se o argumento a não tiver o tipo exigido pela função. Isso é melhor do que a versão original, porque não lança exceção por causa de um tipo estático incompatível. Ele só lança quando precisa lançar, por razões de solidez do sistema de tipos.

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ê.