Menu
Coddy logo textTech

Variáveis Late

Parte da seção Programação Orientada a Objetos do Journey de Dart da Coddy — lição 19 de 110.

A palavra-chave late informa ao Dart que uma variável não anulável será inicializada antes de ser usada, mesmo que não seja atribuída imediatamente. Isso é útil quando você não pode inicializar um campo na declaração ou no construtor, mas tem certeza de que ela terá um valor antes de ser acessada.

class User {
  late String username;
  
  void initialize(String name) {
    username = name;
  }
  
  void greet() {
    print('Hello, $username!');
  }
}

User user = User();
user.initialize('Alice');
user.greet();  // Olá, Alice!

Sem o late, o Dart reclamaria que username não está inicializado. O modificador late promete que você atribuirá um valor antes de lê-lo.

Outro benefício do late é a inicialização preguiçosa (lazy initialization). Uma variável late com um inicializador não computará seu valor até ser acessada pela primeira vez:

class Config {
  late String settings = loadSettings();
  
  String loadSettings() {
    print('Loading...');
    return 'default';
  }
}

Config config = Config();
print('Config created');
print(config.settings);  // "Loading..." é impresso aqui, depois "default"

O método loadSettings() só é executado quando settings é acessado pela primeira vez, não quando o objeto é criado. Tenha cuidado, no entanto - acessar uma variável late antes de ser inicializada lança um erro de tempo de execução.

challenge icon

Desafio

Fácil

Vamos construir um gerenciador de conexão de banco de dados que demonstra tanto a inicialização adiada quanto a inicialização preguiçosa (lazy initialization) usando variáveis late.

Você criará dois arquivos para organizar seu código:

  • database.dart: Defina uma classe Database que simula uma conexão de banco de dados. Sua classe deve ter:
    • Uma late String connectionString que será definida após a criação do objeto
    • Uma late String status com um inicializador preguiçoso que imprime Checking connection... e retorna 'Connected'
    • Um método connect(String connStr) que define a connectionString e imprime Connection configured: [connectionString]
    • Um método query(String sql) que imprime Executing on [connectionString]: [sql]
    • Um método checkStatus() que imprime Status: [status] (isso acionará a inicialização preguiçosa na primeira chamada)
  • main.dart: Importe sua classe de banco de dados e demonstre ambos os usos de late:
    • Crie uma instância de Database
    • Imprima Database object created
    • Chame connect() com a string de conexão 'localhost:5432/mydb'
    • Chame query() com 'SELECT * FROM users'
    • Chame checkStatus() para acionar a inicialização preguiçosa

Observe como connectionString é definida manualmente após a criação do objeto, enquanto status computa seu valor apenas quando é acessada pela primeira vez.

Saída esperada:

Database object created
Connection configured: localhost:5432/mydb
Executing on localhost:5432/mydb: SELECT * FROM users
Checking connection...
Status: Connected

Folha de consulta

A palavra-chave late permite declarar variáveis não anuláveis que serão inicializadas posteriormente, antes de serem usadas:

class User {
  late String username;
  
  void initialize(String name) {
    username = name;
  }
}

User user = User();
user.initialize('Alice');

Inicialização Preguiçosa: Uma variável late com um inicializador calcula seu valor apenas quando é acessada pela primeira vez:

class Config {
  late String settings = loadSettings();
  
  String loadSettings() {
    print('Loading...');
    return 'default';
  }
}

Config config = Config();  // loadSettings() ainda não foi chamado
print(config.settings);     // loadSettings() chamado aqui

Aviso: Acessar uma variável late antes da inicialização lança um erro de tempo de execução.

Experimente você mesmo

import 'database.dart';

void main() {
  // TODO: Criar uma instância do Database
  
  // TODO: Imprimir 'Database object created'
  
  // TODO: Chamar connect() com 'localhost:5432/mydb'
  
  // TODO: Chamar query() com 'SELECT * FROM users'
  
  // TODO: Chamar checkStatus() para acionar a inicialização preguiçosa (lazy initialization)
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Programação Orientada a Objetos