Variáveis Estáticas e Constantes

Variáveis estáticas e constantes são duas maneiras diferentes de criar valores com escopo global que não podem ser movidos ou realocados durante a execução do programa.

const

Constantes são avaliadas em tempo de compilação e seus valores são incorporados onde quer que sejam usados:

const DIGEST_SIZE: usize = 3;
const ZERO: Option<u8> = Some(42);

fn compute_digest(text: &str) -> [u8; DIGEST_SIZE] {
    let mut digest = [ZERO.unwrap_or(0); DIGEST_SIZE];
    for (idx, &b) in text.as_bytes().iter().enumerate() {
        digest[idx % DIGEST_SIZE] = digest[idx % DIGEST_SIZE].wrapping_add(b);
    }
    digest
}

fn main() {
    let digest = compute_digest("Olá");
    println!("Resumo: {digest:?}");
}

De acordo com o Rust RFC Book, eles são expandidos no próprio local (inline) quando utilizados.

Somente funções marcadas como const podem ser chamadas em tempo de compilação para gerar valores const. As funções const podem, entretanto, ser chamadas em tempo de execução.

static

Variáveis estáticas permanecerão válidas durante toda a execução do programa e, portanto, não serão movidas:

static BANNER: &str = "Bem-vindo ao RustOS 3.14";

fn main() {
    println!("{BANNER}");
}

Conforme observado no Rust RFC Book, eles não são expandidos no local (inlined) quando utilizados e possuem um local de memória real associado. Isso é útil para código inseguro (unsafe) e embarcado, e a variável é válida durante toda a execução do programa. Quando um valor de escopo global não tem uma razão para precisar de identidade de objeto, geralmente const é preferido.

Como variáveis estáticas (static) são acessíveis de qualquer thread, elas precisam ser Sync. A mutabilidade interior é possível através de um Mutex, atômico ou similar. Também é possível ter variáveis estáticas mutáveis, mas elas exigem sincronização manual de forma que qualquer acesso a elas requer código “inseguro”. Veremos variáveis estáticas mutáveis no capítulo sobre Unsafe Rust.

  • Mencione que const se comporta semanticamente de maneira similar ao constexpr de C++.
  • Por outro lado, static é muito mais similar a um const ou variável global mutável em C++.
  • static fornece identidade de objeto: um endereço na memória e estado conforme exigido por tipos com mutabilidade interior tais como Mutex<T>.
  • Não é muito comum que alguém precise de uma constante avaliada em tempo de execução, mas é útil e mais seguro do que usar uma variável estática.
  • Dados de thread_local podem ser criados com a macro std::thread_local.

Tabela de propriedades:

PropriedadeStaticConstant
Possui um endereço na memóriaSimNão (inlined, i.e., expandida no local)
É válida durante toda a execução do programaSimNão
Pode ser mutávelSim (inseguro)Não
Avaliada em tempo de compilaçãoSim (inicializada em tempo de compilação)Sim
Inlined (expandida no local) onde quer que seja utilizadaNãoSim