Pular para o conteúdo principal

Variáveis e Tipos

Declaração de variáveis

Em Dart, existem várias formas de declarar variáveis:

var

A palavra-chave var permite que o tipo seja inferido automaticamente pelo compilador:

var nome = "João"; // tipo String
var idade = 25; // tipo int
var altura = 1.75; // tipo double

Tipos explícitos

Você pode declarar o tipo explicitamente:

String nome = "João";
int idade = 25;
double altura = 1.75;
bool isAtivo = true;

final

A palavra-chave final cria uma variável que só pode ser atribuída uma vez. O valor não pode ser alterado após a atribuição inicial:

final nome = "João";
final int idade = 25;

// nome = "Maria"; // Erro! Não é possível alterar uma variável final

const

A palavra-chave const cria uma constante em tempo de compilação. O valor deve ser conhecido em tempo de compilação:

const pi = 3.14159;
const String nome = "João";
const lista = [1, 2, 3];

// const agora = DateTime.now(); // Erro! DateTime.now() não é conhecido em tempo de compilação

Diferença entre final e const: final pode ser atribuído em tempo de execução, enquanto const deve ser conhecido em tempo de compilação.

late

A palavra-chave late permite declarar uma variável não-nula que será inicializada posteriormente:

late String nome;

void inicializar() {
nome = "João"; // Inicialização posterior
print(nome);
}

late é útil quando você sabe que a variável será inicializada antes de ser usada, mas não no momento da declaração.

Null safety

Dart possui um sistema robusto de null safety que previne erros comuns relacionados a valores nulos. Por padrão, variáveis não podem ser nulas:

String nome = "João";
// nome = null; // Erro! String não pode ser nula

Para permitir valores nulos, use o operador ?:

String? nome; // Pode ser null
nome = null; // OK
nome = "João"; // OK

Ao trabalhar com variáveis nullable, você precisa verificar se são nulas antes de usar:

String? nome;

if (nome != null) {
print(nome.length); // OK, nome não é null aqui
}

// Ou use o operador null-aware
print(nome?.length); // Retorna null se nome for null
print(nome?.length ?? 0); // Retorna 0 se nome for null

Default values

Variáveis não inicializadas têm valores padrão:

int? numero; // null
int numero2 = 0; // 0
String? texto; // null
bool? flag; // null
List? lista; // null

Tipos de dados

Numbers

Dart possui dois tipos numéricos:

int: Números inteiros

int idade = 25;
int negativo = -10;
int hex = 0xFF; // Hexadecimal
int binario = 0b1010; // Binário

double: Números de ponto flutuante

double altura = 1.75;
double pi = 3.14159;
double exponencial = 1.2e5; // 120000.0

Ambos são subclasses de num:

num valor = 10; // Pode ser int ou double
valor = 10.5; // OK

Strings

Strings podem ser criadas com aspas simples ou duplas:

String nome1 = 'João';
String nome2 = "Maria";

String interpolation: Você pode inserir expressões dentro de strings:

String nome = "João";
int idade = 25;
String mensagem = "Olá, meu nome é $nome e tenho $idade anos";
String calculo = "O dobro de $idade é ${idade * 2}";

Multiline strings: Use três aspas para strings de múltiplas linhas:

String texto = '''
Esta é uma string
de múltiplas linhas
muito útil para textos longos
''';

Booleans

O tipo bool representa valores verdadeiro ou falso:

bool isAtivo = true;
bool isInativo = false;

if (isAtivo) {
print("Está ativo");
}

Lists

Listas são coleções ordenadas de elementos:

List<int> numeros = [1, 2, 3, 4, 5];
List<String> nomes = ['João', 'Maria', 'Pedro'];

// Lista vazia
List<int> vazia = [];

// Adicionar elementos
numeros.add(6);
numeros.addAll([7, 8, 9]);

// Acessar elementos
print(numeros[0]); // 1
print(numeros.length); // 9

// Lista fixa (não pode adicionar/remover)
List<int> fixa = List.filled(3, 0); // [0, 0, 0]

Maps

Maps são coleções de pares chave-valor:

Map<String, int> idades = {
'João': 25,
'Maria': 30,
'Pedro': 28
};

// Acessar valores
print(idades['João']); // 25

// Adicionar ou atualizar
idades['Ana'] = 22;
idades['João'] = 26;

// Verificar se contém chave
if (idades.containsKey('Maria')) {
print("Maria está no mapa");
}

// Iterar sobre o mapa
idades.forEach((nome, idade) {
print('$nome tem $idade anos');
});

Enums

Enums definem um conjunto fixo de valores constantes:

enum Status {
pendente,
emAndamento,
concluido,
cancelado
}

Status tarefa = Status.pendente;

if (tarefa == Status.pendente) {
print("Tarefa ainda não iniciada");
}

// Acessar valores do enum
print(Status.values); // [Status.pendente, Status.emAndamento, ...]
print(tarefa.name); // "pendente"

Enums com propriedades: Enums podem ter propriedades e métodos associados:

enum Prioridade {
baixa('Baixa', 1),
media('Média', 2),
alta('Alta', 3);

final String descricao;
final int nivel;

const Prioridade(this.descricao, this.nivel);

bool get isUrgente => nivel >= 3;

String get mensagem => 'Prioridade $descricao (nível $nivel)';
}

Prioridade tarefa = Prioridade.alta;
print(tarefa.descricao); // "Alta"
print(tarefa.nivel); // 3
print(tarefa.isUrgente); // true
print(tarefa.mensagem); // "Prioridade Alta (nível 3)"

Este exemplo mostra um enum com múltiplas propriedades (descricao, nivel), um constructor que inicializa essas propriedades, e métodos getter (isUrgente e mensagem) que calculam valores baseados nas propriedades.

Object

Tudo em Dart é um objeto, incluindo números, funções e null:

Object qualquer = "texto";
qualquer = 42;
qualquer = true;

Exercícios

  1. Declaração de variáveis: Crie variáveis usando var, tipos explícitos, final e const. Demonstre a diferença entre elas tentando reatribuir valores.

  2. Null safety: Crie uma função que receba um String? (nullable) e retorne o comprimento da string. Se a string for null, retorne 0. Use operadores null-aware.

  3. Tipos de dados: Crie um programa que demonstre o uso de int, double, String, bool, List e Map. Inclua operações como adicionar elementos a listas e atualizar valores em maps.

  4. String interpolation: Crie uma função que receba nome, idade e cidade, e retorne uma string formatada usando interpolação: "Olá, meu nome é [nome], tenho [idade] anos e moro em [cidade]".

  5. Enums: Crie um enum StatusTarefa com valores pendente, emAndamento, concluida e cancelada. Crie uma função que receba um status e retorne uma mensagem descritiva.

Soluções

Ver solução do exercício 1
void main() {
// var - tipo inferido
var nome = "João";
nome = "Maria"; // OK

// Tipo explícito
int idade = 25;
idade = 26; // OK

// final - atribuído uma vez
final sobrenome = "Silva";
// sobrenome = "Santos"; // Erro! Não pode reatribuir

// const - constante em tempo de compilação
const pi = 3.14159;
// pi = 3.14; // Erro! Não pode reatribuir

print("Nome: $nome, Idade: $idade, Sobrenome: $sobrenome, PI: $pi");
}
Ver solução do exercício 2
int obterComprimento(String? texto) {
return texto?.length ?? 0;
}

void main() {
print(obterComprimento("Dart")); // 4
print(obterComprimento(null)); // 0

// Alternativa usando if
int obterComprimento2(String? texto) {
if (texto != null) {
return texto.length;
}
return 0;
}

print(obterComprimento2("Flutter")); // 7
print(obterComprimento2(null)); // 0
}
Ver solução do exercício 3
void main() {
// int
int idade = 25;
int anoNascimento = 1998;

// double
double altura = 1.75;
double peso = 70.5;

// String
String nome = "João";
String sobrenome = "Silva";

// bool
bool isAtivo = true;
bool temPermissao = false;

// List
List<String> frutas = ['maçã', 'banana'];
frutas.add('laranja');
frutas.addAll(['uva', 'manga']);
print("Frutas: $frutas");

// Map
Map<String, int> idades = {
'João': 25,
'Maria': 30,
};
idades['Pedro'] = 28;
idades['João'] = 26; // Atualiza valor
print("Idades: $idades");

// Operações
print("Idade atual: $idade");
print("Altura: $altura metros");
print("Nome completo: $nome $sobrenome");
print("Ativo: $isAtivo, Permissão: $temPermissao");
}
Ver solução do exercício 4
String apresentar(String nome, int idade, String cidade) {
return "Olá, meu nome é $nome, tenho $idade anos e moro em $cidade";
}

void main() {
String mensagem = apresentar("João", 25, "São Paulo");
print(mensagem);

// Com cálculos na interpolação
String apresentarComCalculo(String nome, int anoNascimento, String cidade) {
int idade = DateTime.now().year - anoNascimento;
return "Olá, meu nome é $nome, tenho $idade anos e moro em $cidade";
}

print(apresentarComCalculo("Maria", 1995, "Rio de Janeiro"));
}
Ver solução do exercício 5
enum StatusTarefa {
pendente,
emAndamento,
concluida,
cancelada
}

String obterMensagemStatus(StatusTarefa status) {
switch (status) {
case StatusTarefa.pendente:
return "A tarefa está aguardando início";
case StatusTarefa.emAndamento:
return "A tarefa está em andamento";
case StatusTarefa.concluida:
return "A tarefa foi concluída";
case StatusTarefa.cancelada:
return "A tarefa foi cancelada";
}
}

void main() {
StatusTarefa status = StatusTarefa.emAndamento;
print(obterMensagemStatus(status));

// Iterar sobre todos os status
for (var s in StatusTarefa.values) {
print("${s.name}: ${obterMensagemStatus(s)}");
}
}