Introdução: "Onde estão as variáveis globais?" — O primeiro choque do iniciante em Rust
\n\nVocê acabou de começar a estudar Rust, escreveu alguns programas e, de repente, percebe: você precisa que alguma variável esteja acessível de qualquer ponto do código. Em Python ou JavaScript, você simplesmente escreveria global_var = 42 no nível superior — e pronto. Mas em Rust... o compilador olha para você com reprovação e emite um erro.
A pergunta "Is it possible to use global variables in Rust?" é uma das mais populares no Stack Overflow. E não é à toa. Rust, ao contrário de muitas linguagens, não permite simplesmente declarar uma variável global. Por quê? Porque segurança de memória não é apenas uma palavra da moda, mas a base da linguagem.
\n\nNeste artigo, vamos explorar todas as formas de trabalhar com dados globais em Rust: desde constantes simples até armazenamentos thread-safe. Você aprenderá como contornar as limitações do compilador sem sacrificar a segurança, e quando variáveis globais são um mal necessário e quando são uma necessidade.
\n\nPor que o Rust proíbe variáveis globais "comuns"?
\n\nAntes de buscar soluções, vamos entender o problema. Rust possui regras estritas de propriedade (ownership) e empréstimo (borrowing). Uma variável global que pode ser alterada de qualquer thread a qualquer momento é um caminho direto para uma condição de corrida (data race).
\n\nImagine: duas threads tentam simultaneamente escrever valores diferentes na mesma variável global. O resultado é imprevisível. Em C++ ou C, isso leva a um comportamento indefinido. Rust garante que isso simplesmente não será compilado.
\n\nPortanto, o compilador exige que especifiquemos explicitamente:
\n- \n
- A variável é imutável? Use
constoustatic. \n - A variável é mutável e usada em uma única thread? Use
static mut(comunsafe). \n - A variável é mutável e usada em várias threads? Use
Mutex,RwLockou tipos atômicos. \n
Método 1: Constantes (const) — a opção mais segura
\n\nSe o seu "valor global" é, na verdade, uma constante que nunca muda, use const:
const MAX_CONNECTIONS: u32 = 100;\nconst DATABASE_URL: &str = "postgresql://localhost:5432/mydb";\n\nfn main() {\n println!("Máximo de conexões: {}", MAX_CONNECTIONS);\n}\n\nConstantes em Rust não são apenas variáveis. Elas são inlineadas pelo compilador no local de uso. Ou seja, durante a compilação, MAX_CONNECTIONS será substituída pelo número 100. Isso é eficiente, mas significa que a constante não tem um endereço fixo na memória. Se você precisar de um local na memória (por exemplo, para FFI), use static.
Método 2: Variáveis estáticas (static)
\n\nSe você precisa de uma variável global com um endereço fixo na memória, use static:
static APP_NAME: &str = "My Rust Application";\nstatic VERSION: u32 = 1;\n\nfn main() {\n println!("Iniciando {} versão {}", APP_NAME, VERSION);\n}\n\nPor padrão, variáveis static são imutáveis. Isso garante segurança em ambientes multithread. Mas e se você precisar alterar o estado global?
Método 3: Variáveis estáticas mutáveis (static mut) — cuidado, unsafe!
\n\nRust permite declarar uma variável estática mutável usando static mut. Mas há um problema: qualquer leitura ou escrita dessa variável requer um bloco unsafe.
static mut COUNTER: u32 = 0;\n\nfn increment() {\n unsafe {\n COUNTER += 1;\n }\n}\n\nfn main() {\n increment();\n unsafe {\n println!("Contador: {}", COUNTER);\n }\n}\n\nImportante: