4
respostas

Erro no construtor da classe ItemTransferencia

Quando adicionei o atributo privado _transferencia à classe ItemTransferencia e mandei o editor criar automaticamente o construtor da classe, ele criou o seguinte método:

const ItemTransferencia({Key key, this._transferencia}) : super(key: key);

e já acusou o seguinte erro: Named optional parameters can't start with an underscore

Como resolvo isso? Pq o construtor criado está diferente do criado durante o curso?

4 respostas

Olá Rodrigo, tudo bem com você?

Acontece que por padrão as IDE's criam os chamados construtores nomeados, que tem parâmetros opcionais ( mais para frente no curso será explicado sobre ele), e inclusive com um campo que na maioria dos casos não iremos utilizar que é o Key :)

E com esse tipo de construtor não é permitido ter campos privados, por isso o erro, de Named optional parameteres can't start with an underscore

O Dart tem uma série de construtores específicos (atributos obrigatórios, atributos opcionais, nomeados), e neste caso queremos o construtor com campos obrigatórios

Então, o correto é trocar para:

ItemTransferencia(this._transferencia)

Esse sim sem as chaves, pode conter campos privados, pois será a esse atributo ( _transferencia que iremos colocar o valor passado na inicialização :)

Sinceramente quando estou desenvolvendo com Flutter, se tem algo que eu evito é pedir para a IDE criar o construtor para mim, pois na maioria das vezes eu terei que apagar o Key, então prefiro fazer na mão mesmo hahahaha

Abraços e Bons Estudos!

Muito obrigado pelas informações, Geovani. Essas pegadinhas das linguagens são sempre complicadas quando a gente começa uma nova. Esse é meu primeiro contato com Dart, apesar de já conhecer várias outras linguagens.

Aproveitando a oportunidade, você saberia me explicar o que é esse ´´´ : super(key: key); ´´´ no método construtor? Procurei na documentação e não achei. Sei que está chamando a classe super e repassando o key a ela, mas não entendi esse dois-pontos. Isso seria o corpo da função? Uma sintaxe alternativa da seta =>?

E mais uma coisa, estranhei um pouco essa sintaxe também de incluir o this. em um nome de parâmetro, na declaração do método. Isso seria algo como a descontrução de objetos do ES6? Ele pega os parâmetros na ordem e já atribui aos atributos da classe? Funciona só para métodos de classes?

Opa Rodrigo,

O Key é como se fosse um id do seu Widget, ele é usado tipicamente para por exemplo: trocar elementos de posição

Para que o estado não seja perdido na troca é necessário ter algo para marcar, e nisso entra as Keys, também temos algumas outras funções, por exemplo, marcar a posição do scroll na tela, e controlar alguns estados globais

A melhor explicação que eu conheço é a do próprio Flutter Team

Está em inglês, mas tem legendas em português caso você prefira :)

mas não entendi esse dois-pontos.

Isso é uma característica bem específica dos construtores do Dart, é a chamada lista inicializadora, é uma parte do código que roda antes mesmo do corpo do construtor, então o super(key:key) está dizendo que a primeira coisa antes de começar a construir o objeto é instanciar a classe mãe passando a key

Vamos utilizar eles para fazer chamadas a classe mãe, fazer alguns asserts ( que também será visto no futuro), e para instanciar campos finais

Vou até juntar isso com a sua outra dúvida

. Isso seria algo como a descontrução de objetos do ES6? Ele pega os parâmetros na ordem e já atribui aos atributos da classe?

Infelizmente o Dart ainda não tem destructuringcom o Javascript, neste caso é apenas uma abstração para facilitar o construtor do Dart, esse código:

ItemTransferencia(this._transferencia)

Equivale a esse:

ItemTransferencia(Transferencia transferencia) : this._transferencia = transferencia

Veja que aparece os :novamente, pois por definição, todo campo finalde nossa estrutura precisar ser instanciado antes do corpo ( no caso na lista inicializadora)

Mas para não ficar algo enorme, no caso de vários campos, temos essa facilidade do Dart, de definir para qual atributo da classe irá o parâmetro do construtor, então é um sintax sugar que serve para construtores

Acabamos utilizando os : principalmente para popular dados que viram de outras formas, por exemplo:

class User {
  final String name;
  final String email;

// Construtor Padrão
  User(this.name, this.email);

  User.fromJson(Map<String, dynamic> json)
      : name = json['name'],
        email = json['email'];

Neste caso temos um construtor nomeado que inicializa 2 campos vindo da decodificação de um json

Mas fica tranquilo, que com o passar do tempo isso vai fazendo mais sentido ahahaha

Abraços e Bons Estudos!

Muito obrigado pela excelente explicação! Estou gostando bastante do curso!