View on GitHub

dart_em_10_minutos

Tudo o que você precisa saber antes do começar com Flutter

Introdução

Com este guia você aprenderá tudo o que é necessário sobre o Dart, para começar sua jornada com o Flutter.

Dart é a melhor linguagem de programação já feita pelo Google.


Sumário


Por que o Flutter usa Dart ?

Dart possibilita que seu código seja executado em 2 tipos diferentes:

Interpretado (JIT = just-in-time): O código é interpretado e executado (neste caso, pela Dart virtual machine), mesmo que já esteja em execução. Assim como acontece no Python ou Javascript.


Compilado (AOT = ahead of time): O código é compilado e executado pela Dart VM. Assim como acontece no Java.

E qual a vantagem?

Para desenvolvedores: Uma experiência incrível, pois o código é interpretado e as alterações são refletidas em menos de 2 segundos.

Para os usuários: Um aplicativo altamente performático, já que o código foi compilado para a plataforma nativa na qual está sendo executado.

Resumindo, este é o motivo!

Mas caso queira se aprofundar, recomendo os materiais abaixo:

Primeiro artigo sobre este assunto

Documentação oficial do Flutter

Vídeo no canal do Flutter


Conceitos importantes


main()

Todo programa Dart (e aplicativos em Flutter, são programas Dart), iniciam na função main():

void main() {
  print('Flutter Bootcamp');
}

Tipos de dados

Básicos:

Existem ainda os tipos Symbols e Runes mas provavelmente não utilizará nenhum deles.

Especiais:

Variáveis

Variáveis armezenam referências. E em Dart, podemos declarar variáveis informando o seu tipo ou não (a tipagem é opcional):

String bootcamp = 'Flutter Bootcamp';

Neste caso, bootcamp armazena a referência para um objeto do tipo String com o valor de “Flutter Bootcamp”.

E esta sintaxe se aplica para todos os outros tipos de dados:

int lancamento = 2021;
double versao = 2.0;
List<String> aplicativos = ['Tempus', 'Menuo', 'Libria', 'Civitas'];
Map<String, Object> informacoes = {
  'tags': ['flutter','dart'],
  'descricao': 'Treinamento completo em Flutter',
  'aplicativos': 6
};

Inferência

A declaração de tipos em Dart é opcional, ou seja, ambas declarações abaixo são válidas:

//tipo String declarado
String bootcampTipado = 'Flutter Bootcamp';

// tipo não declarado
var bootcampSemTipo = 'Flutter Bootcamp';

Por inferência, o Dart consegue identificar que bootcampSemTipo é do tipo String devido ao valor atribuido.

E o mesmo se aplica para todos os outros tipos de dados.

// int
var lancamento = 2021;

// double
var versao = 1.0;

// List<String>
var aplicativos = ['Tempus', 'Menuo', 'Libria', 'Civitas'];

// Map<String, Object>
var informacoes = {
  'tags': ['flutter','dart'],
  'descricao': 'Treinamento completo em Flutter',
  'aplicativos': 6
};

var / const / final

Estes são os modificadores possíveis ao declarar variáveis:

var: Permite que o valor atribuído seja alterado.

final: O valor não pode ser alterado e não é conhecido em tempo de execução.

const: O valor não pode ser alterado e ja é conhecido em tempo de execução.

Sempre que possível, utilize const.

Null Safety

Desde a versão 2.12 (liberada em março de 2021), Dart suporta o modo null safety por padrão.

Isso significa que devemos declarar explicitamente que uma variável pode ter valor null. Caso contrário, o compilador indicará um erro:.

int idade;
print(idade);

 The non-nullable local variable 'idade' must be assigned before it can be used.

Este erro ocorre pois estamos acessando idade antes de atribuir um valor à ela.

Ao utilizar o operador ?, indicamos ao compilador que a variável pode ter valor null.

int? idade;
print(idade);

 será imprimido o valor null

Operadores

Dart é uma linguagem moderna e possui todos os tipos de operadores tradicionais:

==, !=, &&, ||, >, >=, +=, !, e muitos outros.

Porém, precisamos destacar 3 que são amplamento utilizados:

if

if (condicao) {

}
if (condicao) {

} else {

}
if (condicao) {

} else if (outraCondicao){

} else {

}

switch

switch (variavel) {
  case: valor1; 
	break;
  case: valor2;
	break;
  default; // opcional, acionado caso variavel não seja valor1 ou valor2		
}

while

var ano = 2021;
while (ano < 2050) {
  ano++;
}
var ano = 2021;
do {
  ano++;
} while (ano < 2050);

for

for (var i = 0; i < 5; i++) {

}
for (item in minhaLista) {

}

Funções

São instruções de código que executadas em sequência.

Em Dart funções são objetos e do tipo Function, ou seja, podem ser atribuídas às variáveis ou passadas como parâmetros.

bool isMaiorDeIdade(int idade) {
  return idade >= 18;
}

Funções que executam apenas 1 instruçãos, podem ser declaradas usando a sintáxe => :

bool isMaiorIdade(int idade) => idade > 18;

Classes

Fornecem uma estrutura para a criação de objetos.

class FlutterBootcamp {

  // atributos
  int? aplicativos;
  String? descricao;
  List<String>? tags;

  // construtor default(opcional)
  FlutterBootcamp();
  FlutterBootcamp(int aplicativos, String descricao, List<String> tags ){
    this.aplicativos = aplicativos;
    this.descricao = descricao;
    this.tags = tags;
  };
  FlutterBootcamp(this.aplicativos, this.descricao, this.tags);
  /*
    Todas as declarações acima são válidas como construtor default da classe. 
    Porém, só é possível utilizar 1 delas.
    Lembre-se: declarar o construtor default é opcional 
  */

  // funções
  void exibirConteudo(){

  }

}

No Flutter, outra funcionalidade muito utilizada da linguagem Dart são os named constructors:

class Carro{
  String? marca;
  int? ano;
  double? motor;

  Carro.popular(){
    motor = 1.0;
  }

  Carro.novo():
    ano = 2021;

  Carro.tesla(this.ano, this.motor):
    marca = 'Tesla';
}

Agora, pode-se criar uma instância do objeto Carro da seguinte forma:

// gol possui motor=1.0
var gol = Carro.popular();

// corollaCross possui ano=2021
var corollaCross = Carro.novo();

// modelS possui marca='Tesla', ano=2020, motor=2.0
var modelS = Carro.tesla(2020, 2.0);

Coleções

// List (os itens podem ser duplicados)
var aplicativos = ['libria', 'menuo', 'civitas'];

// Por inferência, aplicativos é um List<String>
// Set (os itens são únicos)
var aplicativos = {'libria', 'menuo', 'civitas'};

// Por inferência, aplicativos é um Set<String>
// Map 
var aplicativos = {
  1 : 'libria', 
  2 : 'menuo', 
  3 : 'civitas'
 };

 // Por inferência, aplicativos é um Map<int, String>

try / catch / finally

try {
  
} catch (e) {

} finally { // opcional
  
}

Future

São objetos utilizados para tratar operações assíncronas (sem sincronia).

Alguns exemplos:

Qualquer operação que não seja concluída imediatamente é uma operação assíncrona.

Future é um objeto que representa uma operação assíncrona. Assim que a operação for concluída, o valor está pronto para ser usado.

void consultarTotalCommits() {
  // quando buscarApi() concluir seu processamento, a função then() será executada e a variável total terá o valor foi retornado da API.
  Future<int> totalCommits = buscarApi();
  totalCommits.then((total) => tratarRetorno(total));
}

O compilador não irá esperar o retorno da API continuar o processamento.

async / await

As palavras-chave async e await, permitem escrever código com operações assíncronas similar à operações síncronas.

O código anterior, com async e await, poderia ser escrito da seguinte forma:

// deve-se usar async para indicar o uso do await dentro de uma função
void consultarTotalCommits() async {
  // usando o await, fará o compilador esperar até que buscarApi() conclua seu processamento
  int totalCommits = await buscarApi();
  tratarRetorno(total);
}

O compilador irá esperar o retorno da API para continuar o processamento.

E agora ?

Parabéns! 👏

Tudo sobre linguagem Dart necessário para começar com Flutter já foi apresentado.

Porém, ainda existem muitos recursos para serem explorados.

Para continuar os estudos e se aprofundar, acesse o guia:

A tour of the Dart language

E também os cursos do Google Codelabs.

Com DartPad, é possível experimentar a linguagem diretamente no browser.

Bons estudos 📖

Referências

A tour of the Dart language

Language samples