Dart: Variáveis e Tipos de Dados no Dart

Última atualização: 2026-08-26

Variáveis são contêineres para dados, e tipos são a forma do contêiner — escolha o contêiner certo, e seu código será seguro.

1. O que Você Aprenderá


2. A História Real de um Desenvolvedor

(1) Dor: Crashes em tempo de execução causados por declarações de variáveis descuidadas

Quando Bob estava desenvolvendo a versão inicial do DataPipeline, declarou todas as variáveis com var e frequentemente alterava seus tipos no meio do caminho. Durante uma refatoração, ele mudou int orderCount para String orderCount por engano. A compilação não reportou erro (tipo dinâmico), mas em tempo de execução, orderCount * price lançou uma exceção, causando a interrupção do processamento em lote de 500.000 pedidos e atrasando a entrega do relatório em 4 horas.

(2) A Solução Type-Safe

O Dart oferece uma gama de métodos de declaração, do mais livre ao mais restrito: const (constante em tempo de compilação) → final (constante em tempo de execução) → var (tipo inferido) → late (inicialização preguiçosa) → dynamic (tipo dinâmico). Usá-los adequadamente permite que o compilador ajude você a encontrar bugs.

DART
// Melhor prática para configuração do DataPipeline
const int maxRecords = 1000000;       // Constante em tempo de compilação
final String pipelineName;             // Constante em tempo de execução (definida uma vez)
var processedCount = 0;                // Inferido como int, mutável
late String outputPath;                // Inicializado depois
// dynamic deve ser evitado se possível
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

(3) Benefícios


3. Cinco Métodos de Declaração

(1) Árvore de Decisão de Métodos de Declaração

100%
graph LR
  subgraph Declarações
    A[var] --> B[Inferência de tipo]
    C[final] --> D[Constante em tempo de execução]
    E[const] --> F[Constante em tempo de compilação]
    G[late] --> H[Inicialização preguiçosa]
    I[dynamic] --> J[Tipo dinâmico]
  end
  subgraph Tipos Integrados
    K[int] --- L[double]
    M[String] --- N[bool]
  end
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: var — Inferência de Tipo

DART
void main() {
  var name = 'DataPipeline';   // Inferido como String
  var count = 1000;            // Inferido como int
  var rate = 0.08;             // Inferido como double

  // Pode reatribuir mesmo tipo
  name = 'Analytics';          // OK - ainda String
  count = 2000;                // OK - ainda int

  // Não pode mudar o tipo
  // count = 'two thousand';   // Erro de compilação!
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: final — Constante em Tempo de Execução

DART
void main() {
  // Definida uma vez em tempo de execução
  final DateTime startTime = DateTime.now();
  final String configPath = '/etc/datapipeline/config.yaml';

  // Não pode reatribuir
  // configPath = '/other/path';  // Erro de compilação!

  // final com coleção - conteúdo pode mudar
  final List<String> sources = ['orders.csv', 'products.csv'];
  sources.add('customers.csv');   // OK - modificando conteúdo
  // sources = ['new_list'];       // Erro - não pode reatribuir referência
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: const — Constante em Tempo de Compilação

DART
void main() {
  // Deve ser conhecido em tempo de compilação
  const int maxRecords = 1000000;
  const double taxRate = 0.08;
  const String version = '1.0.0';

  // Coleções const são imutáveis em profundidade
  const List<String> formats = ['json', 'csv', 'html'];
  // formats.add('xml');  // Erro! Não pode modificar lista const

  // Construtor const
  const config = PipelineConfig(batchSize: 10000);
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: late — Inicialização Preguiçosa

DART
class DataPipeline {
  late String outputPath;  // Será definido depois

  void configure(String path) {
    outputPath = path;
  }

  late final int maxRecords = _loadMaxRecords();  // Calculado no primeiro acesso

  int _loadMaxRecords() {
    print('Carregando configuração de max records...');
    return 1000000;
  }
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: dynamic — Tipo Dinâmico

DART
void main() {
  dynamic value = 'hello';   // String
  value = 42;                // OK - agora int
  value = [1, 2, 3];        // OK - agora List

  // Sem verificação de tipo em tempo de compilação - arriscado!
  // value.nonExistentMethod();  // Sem erro de compilação, crash em tempo de execução

  // Prefira Object? em vez de dynamic quando precisar de flexibilidade
  Object? safeValue = 'test';
  // safeValue.nonExistentMethod();  // Erro de compilação - mais seguro
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

(2) Comparação dos Cinco Métodos de Declaração

Método de Declaração Tipo Mutável Momento da Inicialização Segurança Caso de Uso
const Determinado em tempo de compilação Imutável Na declaração Mais alta Constantes de configuração, valores de enum
final Determinado em tempo de execução Imutável Na declaração ou no construtor Alta Configuração em tempo de execução, valores injetados
var Inferido Mutável Na declaração Média Variáveis locais, contadores
late Anotado explicitamente Mutável Adiada Média Campos de inicialização adiada
dynamic Tempo de execução Mutável A qualquer momento Baixa Parsing de JSON, interoperabilidade

4. Tipos Integrados em Detalhes

(1) Tipos Numéricos

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: int e double

DART
void main() {
  int orderCount = 1500;
  double totalAmount = 52500.75;
  num genericNum = 42;      // num é supertipo de int e double
  genericNum = 3.14;        // OK - num aceita ambos

  // Operações aritméticas
  double avgOrderValue = totalAmount / orderCount;
  int roundedDown = totalAmount.toInt();

  // Métodos convenientes
  print(totalAmount.toStringAsFixed(2));  // 52500.75
  print(orderCount.isEven);              // false (1500 é par, true)
  print(orderCount.clamp(0, 1000));      // 1000 (limitado ao máximo)
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.
Tipo Intervalo Propósito
int 64 bits (varia no JS) Contagem, indexação
double 64 bits IEEE 754 Valores, proporções
num Supertipo de int + double Valores numéricos gerais

(2) Tipo String

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: Interpolação de Strings e Operações

DART
void main() {
  // Interpolação de strings
  String product = 'DataPipeline';
  int users = 5000;
  print('$product tem $users usuários');               // Interpolação simples
  print('Receita: ${users * 99} USD');              // Interpolação com expressão
  print('Média: ${(125000 / users).toStringAsFixed(2)} USD');

  // Strings de múltiplas linhas
  String description = '''
  DataPipeline - Ferramenta de Análise de E-Commerce
  Processa até 1.000.000 pedidos por lote
  Suporta formatos de saída JSON, CSV e HTML
  ''';

  // Raw strings (sem processamento de escape)
  String path = r'C:\Users\Bob\data\orders.csv';
  String regex = r'\d{4}-\d{2}-\d{2}';  // Padrão de data

  // Métodos úteis
  String raw = '  Hello, World!  ';
  print(raw.trim());                  // 'Hello, World!'
  print(raw.toUpperCase());           // '  HELLO, WORLD!  '
  print('USD 1,500.00'.replaceAll(',', ''));  // 'USD 1500.00'
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.
Recurso Sintaxe Exemplo
Interpolação simples $variable '$name'
Interpolação com expressão ${expr} '${a + b}'
Strings de múltiplas linhas '''...''' Triplas aspas
Raw strings r'...' r'\n' permanece como está

(3) Tipo bool

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: Valores Booleanos e Condições

DART
void main() {
  bool isProduction = true;
  bool isDebug = false;

  // Dart exige bool explícito em condições
  int count = 0;
  // if (count) {}  // Erro! Deve ser bool
  if (count > 0) {  // OK - comparação explícita
    print('Tem registros');
  }

  // Operadores lógicos
  bool shouldProcess = isProduction && !isDebug;
  bool hasData = count > 0 || isProduction;
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

5. Inferência de Tipos e Anotação Explícita

(1) Melhores Práticas

DART
// Bom - deixe o compilador inferir para variáveis locais
var name = 'DataPipeline';     // Inferido String
var count = 100;               // Inferido int
var items = <String>[];        // Genérico explícito, inferido List

// Bom - tipo explícito para API pública
String get displayName => name;
int get maxCapacity => 1000000;

// Bom - final para valores que não mudam
final startTime = DateTime.now();

// Evitar - tipo explícito desnecessário em locais
// String name = 'DataPipeline';  // Redundante
// int count = 100;               // Redundante
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.
Cenário Recomendação Motivo
Variáveis locais var / final Reduz redundância, inferência é suficiente
API pública Anotação explícita Documentação clara, interface estável
Genéricos de coleção Genérico explícito Evita inferência como List<dynamic>
Parâmetros de construtor Anotação explícita Contrato claro

6. Cenário do Bob: Variáveis de Configuração do DataPipeline

▶ Exemplo

TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

: Design de Variáveis de Configuração

DART
// Constantes de configuração do DataPipeline
const String appName = 'DataPipeline';
const int defaultBatchSize = 10000;
const double defaultTaxRate = 0.08;

// Configuração em tempo de execução
class PipelineConfig {
  final String version;
  final int batchSize;
  final String outputFormat;

  PipelineConfig({
    this.version = '1.0.0',
    this.batchSize = defaultBatchSize,
    this.outputFormat = 'json',
  });

  @override
  String toString() =>
      '$appName v$version | Lote: $batchSize | Formato: $outputFormat';
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

7. Exemplo Completo: Declaração de Variáveis do DataPipeline na Prática

DART
// ============================================
// Demo de Declaração de Variáveis do DataPipeline
// Mostra o uso adequado de todos os tipos de declaração
// ============================================

// Constantes em tempo de compilação - nunca mudam entre execuções
const String appName = 'DataPipeline';
const int maxRecords = 1000000;
const double taxRate = 0.08;
const List<String> supportedFormats = ['json', 'csv', 'html'];

class Order {
  final String id;          // Constante em tempo de execução após construção
  final double amount;      // Constante em tempo de execução após construção
  late String status;       // Será definida pela lógica de processamento

  Order({required this.id, required this.amount});

  double get tax => amount * taxRate;
  double get total => amount + tax;

  String get formattedAmount =>
      '\$${amount.toStringAsFixed(2)} USD';
}

class DataPipeline {
  final String name;
  var processedCount = 0;              // Contador mutável
  late final DateTime startTime;       // Definido na primeira execução

  DataPipeline({required this.name});

  void start() {
    startTime = DateTime.now();
    print('$appName iniciado em $startTime');
  }

  void processOrder(Order order) {
    processedCount++;
    order.status = 'processed';
    print('Pedido ${order.id}: ${order.formattedAmount} '
        '(imposto: \$${order.tax.toStringAsFixed(2)} USD)');
  }

  void printSummary() {
    print('\n=== Resumo ===');
    print('Pipeline: $name');
    print('Processados: $processedCount pedidos');
    print('Capacidade: $processedCount / $maxRecords');
  }
}

void main() {
  final pipeline = DataPipeline(name: 'E-Commerce Analytics');
  pipeline.start();

  final orders = [
    Order(id: 'ORD-001', amount: 1500.00),
    Order(id: 'ORD-002', amount: 3250.50),
    Order(id: 'ORD-003', amount: 890.25),
  ];

  for (final order in orders) {
    pipeline.processOrder(order);
  }

  pipeline.printSummary();
}
TEXT 📖 Somente leitura
> **Saída:** Execute em seu DartPad local ou com `dart run`. Todos os exemplos do curso Dart são baseados em Dart 3.x / Flutter 3.x, e os resultados podem variar ligeiramente dependendo da versão do SDK.

Saída:

TEXT 📖 Somente leitura
DataPipeline iniciado em 2024-01-15 10:30:00.000
Pedido ORD-001: $1500.00 USD (imposto: $120.00 USD)
Pedido ORD-002: $3250.50 USD (imposto: $260.04 USD)
Pedido ORD-003: $890.25 USD (imposto: $71.22 USD)

=== Resumo ===
Pipeline: E-Commerce Analytics
Processados: 3 pedidos
Capacidade: 3 / 1000000

❓ Perguntas Frequentes

P: Qual devo usar, var ou final? R: Se a variável não será reatribuída, prefira final. Se precisar modificá-la, use var. A regra de lint oficial do Dart prefer_final_locals recomenda priorizar final.

P: Qual a diferença entre const e final? R: const é uma constante em tempo de compilação; seu valor deve ser determinado em tempo de compilação. final é uma constante em tempo de execução; só pode ser atribuída uma vez, mas seu valor pode ser calculado em tempo de execução. DateTime.now() não pode ser const.

P: Quando devo usar late? R: Use late quando uma variável não pode ser inicializada no ponto de declaração, mas você pode garantir que será inicializada antes do uso. Cenários comuns incluem injeção de dependência e configuração pós-construção. Uso incorreto levará a um LateInitializationError em tempo de execução.

P: Qual a diferença entre dynamic e Object?? R: dynamic desliga toda verificação de tipos; o compilador não verifica nenhuma chamada de método. Object? mantém a verificação de tipos; você só pode chamar métodos de Object. Prefira Object? quando precisar de flexibilidade.

P: O int do Dart é o mesmo na Web e na VM? R: Não exatamente. Na VM do Dart, int é um inteiro de 64 bits. Quando compilado para JS, int está sujeito às limitações do JS Number (precisão de 53 bits). Tenha cautela com aritmética de números grandes.

P: Posso usar aspas simples ou duplas para String? R: Ambas são aceitas e têm exatamente o mesmo efeito. O guia de estilo oficial do Dart recomenda aspas simples, usando aspas duplas apenas quando a string em si contém uma aspa simples.

P: Quando devo usar o tipo num? R: Use num quando precisar que um parâmetro ou variável aceite tanto int quanto double. num é o supertipo de int e double e suporta operações aritméticas básicas.


📖 Resumo


📝 Exercícios

  1. Básico (Dificuldade ⭐): Declare as seguintes variáveis: um nome de aplicação const, um horário atual final, e um contador var. Imprima seus valores e tipos respectivamente.
  2. Intermediário (Dificuldade ⭐⭐): Escreva uma função que aceita um parâmetro do tipo num e retorna uma string formatada em USD desse número (ex: formatUSD(1500.5) retorna "$1,500.50 USD"). Trate tanto entradas int quanto double.
  3. Avançado (Dificuldade ⭐⭐⭐): Design uma classe Config que usa late para inicializar preguiçosamente uma string de conexão de banco de dados, usa const para definir valores padrão, e usa final para armazenar configuração lida de variáveis de ambiente. Demonstre a colaboração desses três métodos de declaração.

← Aula Anterior | Próxima Aula →

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%