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 de late é a inicialização tardia. Uma variável late com um inicializador não calculará 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 criar um gerenciador de conexão com banco de dados que demonstra tanto a inicialização adiada quanto a inicialização lenta usando variáveis late.

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

  • database.dart: Defina uma classe Database que simula uma conexão com banco de dados. Sua classe deve ter:
    • Uma late String connectionString que será definida depois que o objeto for criado
    • Uma late String status com um inicializador lento que imprime Checking connection... e retorna 'Connected'
    • Um método connect(String connStr) que define 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 lenta na primeira chamada)
  • main.dart: Importe sua classe de banco de dados e demonstre os dois 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 lenta

Observe como connectionString é definida manualmente depois da criação do objeto, enquanto status calcula seu valor somente 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

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

Pratique por conta própria: Compilador de Dart online