Biblioteca once_cell para Rust: inicialização tardia e células únicas
O que é e por que usar
A biblioteca once_cell é uma das mais populares e úteis do ecossistema Rust, projetada para implementar o padrão de inicialização tardia (lazy initialization) e criar células únicas (once cells). Ela fornece dois tipos principais: OnceCell e Lazy, que resolvem um problema fundamental — criar um valor de forma adiada, que é inicializado apenas uma vez no primeiro acesso.
Por que isso é necessário? No Rust, como em qualquer outra linguagem, é comum surgir situações onde criar um objeto é uma operação cara (por exemplo, ler um arquivo de configuração, estabelecer uma conexão com banco de dados, carregar um dicionário grande). Se esse objeto não for necessário imediatamente ao iniciar o programa, mas apenas em condições específicas, sua inicialização pode ser adiada. O once_cell faz isso de forma segura e eficiente, garantindo que a inicialização ocorra exatamente uma vez, mesmo com acesso concorrente de várias threads.
Antes do once_cell ser incorporado à biblioteca padrão do Rust (a partir da versão 1.70.0 com std::cell::OnceCell e std::sync::OnceLock), esta biblioteca era o padrão de facto para inicialização tardia. Ela continua relevante hoje devido à sua maturidade, amplo conjunto de funcionalidades e compatibilidade com versões anteriores. A biblioteca oferece não apenas versões thread-safe (sync), mas também versões single-thread (unsync) dos tipos, permitindo evitar a sobrecarga de sincronização onde ela não é necessária.
Instalação
Para usar o once_cell, adicione-o às dependências do seu projeto no Cargo.toml:
[dependencies]
once_cell = "1.20"
Ou execute o comando:
cargo add once_cell
Depois disso, você pode importar os tipos necessários:
use once_cell::sync::{OnceCell, Lazy};
// ou para uso single-thread:
use once_cell::unsync::{OnceCell as UnsyncOnceCell, Lazy as UnsyncLazy};
Início rápido
Um exemplo mínimo funcional usando Lazy para inicialização tardia de uma variável estática:
use once_cell::sync::Lazy;
use std::collections::HashMap;
// A variável estática será inicializada apenas no primeiro acesso
static CONFIG: Lazy<HashMap<String, String>> = Lazy::new(|| {
println!("Inicializando configuração...");
let mut map = HashMap::new();
map.insert("host".to_string(), "localhost".to_string());
map.insert("port".to_string(), "8080".to_string());
map
});
fn main() {
// Primeiro acesso — a inicialização ocorre aqui
println!("Host: {}", CONFIG.get("host").unwrap());
// Segundo acesso — a inicialização NÃO ocorre, usa o valor em cache
println!("Porta: {}", CONFIG.get("port").unwrap());
}
Saída do programa:
Inicializando configuração...
Host: localhost
Porta: 8080
Principais métodos e funções
Vamos explorar 8 métodos e funções principais da biblioteca once_cell com exemplos de uso.
1. OnceCell::new()
Assinatura: pub const fn new() -> OnceCell<T>
O que faz: Cria uma nova célula vazia que ainda não contém um valor.
use once_cell::sync::OnceCell;
let cell: OnceCell<i32> = OnceCell::new();
assert!(cell.get().is_none()); // A célula está vazia
2. OnceCell::set()
Assinatura: pub fn set(&self, value: T) -> Result<(), T>
Também na biblioteca
Geração de relatórios PDF em PHP: visão geral das bibliotecas e exemplos
StoreKit para Swift: guia completo com exemplos
Frameworks CLI para PHP: criando aplicações de console com Symfony Console e Laravel Zero
Processamento de Markdown em Node.js: bibliotecas marked, showdown e remarkable